home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1995…tember: Reference Library / Dev.CD Sep 95 RL / Dev.CD Sep 95 RL.toast / mac / Technical Documentation / develop / develop Issue 6 code / TCP / NewsWatcher / NW Source / Source / prefsdlog.c < prev    next >
Encoding:
C/C++ Source or Header  |  1995-06-04  |  64.0 KB  |  2,324 lines  |  [TEXT/MMCC]

  1. /*----------------------------------------------------------------------------
  2.  
  3.     prefsdlog.c
  4.  
  5.     This module handles the preferences dialog.
  6.     
  7.     Copyright © 1994-1995, Northwestern University.
  8.  
  9. ----------------------------------------------------------------------------*/
  10.  
  11. #include <stdio.h>
  12. #include <string.h>
  13. #include <ctype.h>
  14.  
  15. #include "glob.h"
  16. #include "prefsdlog.h"
  17. #include "dialog.h"
  18. #include "popuputil.h"
  19. #include "sfutil.h"
  20. #include "log.h"
  21. #include "news.h"
  22. #include "newswatcher.h"
  23. #include "strutil.h"
  24. #include "full.h"
  25. #include "drawutil.h"
  26. #include "memutil.h"
  27. #include "fileutil.h"
  28. #include "apputil.h"
  29. #include "resutil.h"
  30. #include "menus.h"
  31. #include "url.h"
  32. #include "ic.h"
  33. #include "header.h"
  34. #include "qsort.h"
  35. #include "listutil.h"
  36. #include "arrowpair.h"
  37.  
  38.  
  39.  
  40. /* Items common to all topics. The kInit and kTerm items are pseudo-items
  41.    used to intialize and terminate the topics. The OK and Cancel buttons
  42.    are also common to all topics (item numbers 1 and 2). Items 3 through
  43.    7 are user items to draw the 5 segments of the gray outline. Item 8
  44.    is the topic popup menu. Item 9 is the user item for the up and down
  45.    arrow controls. Item 10 is the help item for help balloons. Item 11 is 
  46.    the user item to outline the OK button. */
  47.  
  48. #define kInit                100
  49. #define kTerm                101
  50. #define kFirstGrayLine        3
  51. #define kLastGrayLine        7
  52. #define kTopicPopup            8
  53. #define kArrows                9
  54. #define kCommonItems        11
  55.  
  56. /* Prefs dialog and DITL resources */
  57.  
  58. #define kPrefsDlg                300
  59. #define kNewsreadingOptions        1
  60. #define kServerAddresses        2
  61. #define kServerOptions            3
  62. #define kPersonalInfo            4
  63. #define kSignature                5
  64. #define kMessageOptions            6
  65. #define kExtraHeaderLines        7
  66. #define kRemoteHost                8
  67. #define kScreenFonts            9
  68. #define kPrintingFont            10
  69. #define kSavedUserGroupLists    11
  70. #define kSavedArticles            12
  71. #define kSavedMessages            13
  72. #define kURLHelpers                14
  73. #define kAuthentication            15
  74. #define kExtractBinaries        16
  75. #define kMiscOptions            17
  76.  
  77. #define kNumTopics                17
  78.  
  79. /* Newsreading options topic. */
  80.  
  81. #define kShowAuthors            (kCommonItems + 1)
  82. #define kShowArtHeaders            (kCommonItems + 2)
  83. #define kCollapseThreads        (kCommonItems + 3)
  84. #define kKeyboardShortcuts        (kCommonItems + 4)
  85. #define kKeypadShortcuts        (kCommonItems + 5)
  86. #define kReuseArticleWinds        (kCommonItems + 6)
  87. #define kReturnToSubjectWindow    (kCommonItems + 7)
  88. #define kStopAtEndOfSubjectList    (kCommonItems + 8)
  89. #define kBeepAtEndOfLists        (kCommonItems + 9)
  90. #define kMaxArticles            (kCommonItems + 11)
  91.  
  92. /* Server info topic. */
  93.  
  94. #define kNewsServer            (kCommonItems + 3)
  95. #define kMailServer            (kCommonItems + 5)
  96.  
  97. /* Server options topic. */
  98.  
  99. #define kBatchedGroupCmds    (kCommonItems + 2)
  100. #define kUseXPAT            (kCommonItems + 3)
  101. #define kNoNewConnection    (kCommonItems + 4)
  102. #define kNoModeReader        (kCommonItems + 5)
  103.  
  104. /* Personal info topic. */
  105.  
  106. #define kFullName            (kCommonItems + 3)
  107. #define kOrganization        (kCommonItems + 5)
  108. #define kMailAddress        (kCommonItems + 7)
  109.  
  110. /* Signature topic. */
  111.  
  112. #define kSigStaticText        (kCommonItems + 1)
  113. #define kSignatureEditText    (kCommonItems + 2)
  114. #define kAddSigBlankLine    (kCommonItems + 3)
  115. #define kAddSigSeparator    (kCommonItems + 4)
  116.  
  117. /* Message options topic. */
  118.  
  119. #define kMsgReplyPost        (kCommonItems + 1)
  120. #define kMsgReplyEmail        (kCommonItems + 2)
  121. #define kMsgCopySelf        (kCommonItems + 3)
  122. #define kMsgShowMsgDetails    (kCommonItems + 4)
  123. #define kMsgWrapOnSend        (kCommonItems + 5)
  124. #define kMsgShowLabels        (kCommonItems + 6)
  125. #define kMsgTabEnabled        (kCommonItems + 7)
  126. #define kMsgTabStops        (kCommonItems + 9)
  127. #define kMsgQuoteString        (kCommonItems + 11)
  128.  
  129. /* Extra header lines topic */
  130.  
  131. #define kMsgExtraNewsHdrLines    (kCommonItems + 2)
  132. #define kMsgExtraMailHdrLines    (kCommonItems + 4)
  133.  
  134. /* Remote host info topic. */
  135.  
  136. #define    kRemoteHostAddr        (kCommonItems + 3)
  137. #define    kRemoteLogin        (kCommonItems + 5)
  138. #define    kRemotePassword        (kCommonItems + 7)
  139. #define kRemotePath            (kCommonItems + 9)
  140. #define kAutoGetPut            (kCommonItems + 10)
  141. #define    kSavePassword        (kCommonItems + 11)
  142.  
  143. /* Screen fonts topic. */
  144.  
  145. #define kListFontPopup         (kCommonItems + 2)
  146. #define kListSizeBox        (kCommonItems + 4)
  147. #define kListSizePopup        (kCommonItems + 5)
  148. #define kListSample            (kCommonItems + 6)
  149. #define kListVertLine        (kCommonItems + 7)
  150. #define kTextFontPopup        (kCommonItems + 9)
  151. #define kTextSizeBox        (kCommonItems + 11)
  152. #define kTextSizePopup        (kCommonItems + 12)
  153. #define kTextSample            (kCommonItems + 13)
  154.  
  155. /* Printing font topic. */
  156.  
  157. #define kPrintingFontPopup         (kCommonItems + 1)
  158. #define kPrintingSizeBox        (kCommonItems + 3)
  159. #define kPrintingSizePopup        (kCommonItems + 4)
  160. #define kPrintingSample            (kCommonItems + 5)
  161.  
  162. /* Saved user group lists topic. */
  163.  
  164. #define kSavedUGLDirCheckBox    (kCommonItems + 1)
  165. #define kSavedUGLDirBorder        (kCommonItems + 2)
  166. #define kSavedUGLDirName        (kCommonItems + 3)
  167. #define kSavedUGLDirButton        (kCommonItems + 4)
  168. #define kSavedUGLAutoSaveOnQuit    (kCommonItems + 5)
  169.  
  170. /* Saved articles topic. */
  171.  
  172. #define kSavedArtAppBorder        (kCommonItems + 2)
  173. #define kSavedArtAppName        (kCommonItems + 3)
  174. #define kSavedArtAppButton        (kCommonItems + 4)
  175. #define kSavedArtDirCheckBox     (kCommonItems + 5)
  176. #define kSavedArtDirBorder        (kCommonItems + 6)
  177. #define kSavedArtDirName        (kCommonItems + 7)
  178. #define kSavedArtDirButton        (kCommonItems + 8)
  179. #define kSavedArtSepFiles        (kCommonItems + 9)
  180. #define kSavedArtAutoAppend        (kCommonItems + 10)
  181. #define kSavedArtSaveEncoded    (kCommonItems + 11)
  182.  
  183. /* Saved messages topic. */
  184.  
  185. #define kSavedMsgDirCheckBox     (kCommonItems + 1)
  186. #define kSavedMsgDirBorder        (kCommonItems + 2)
  187. #define kSavedMsgDirName        (kCommonItems + 3)
  188. #define kSavedMsgDirButton        (kCommonItems + 4)
  189. #define kSavedMsgDelAfterSend    (kCommonItems + 5)
  190.  
  191. /* URL helper programs topic. */
  192.  
  193. #define kURLList            (kCommonItems + 1)
  194. #define kURLChangeButton    (kCommonItems + 2)
  195. #define kURLDeleteButton    (kCommonItems + 3)
  196. #define kURLNewScheme        (kCommonItems + 5)
  197. #define kURLAddButton        (kCommonItems + 6)
  198. #define kURLUseWebHelper    (kCommonItems + 7)
  199.  
  200. /* Authentication topic. */
  201.  
  202. #define kAuthUsername        (kCommonItems + 3)
  203. #define kAuthPassword        (kCommonItems + 5)
  204. #define kAuthSavePassword    (kCommonItems + 6)
  205. #define kAuthPrivateGroups    (kCommonItems + 7)
  206. #define kAuthWhenRequested    (kCommonItems + 8)
  207. #define kAuthAtStartup        (kCommonItems + 9)
  208.  
  209. /* Extracting Binaries topic. */
  210.  
  211. #define kSavedBinDirCheckBox    (kCommonItems + 1)
  212. #define kSavedBinDirBorder        (kCommonItems + 2)
  213. #define kSavedBinDirName        (kCommonItems + 3)
  214. #define kSavedBinDirButton        (kCommonItems + 4)
  215. #define kHqxAppBorder            (kCommonItems + 6)
  216. #define kHqxAppName                (kCommonItems + 7)
  217. #define kHqxAppButton            (kCommonItems + 8)
  218. #define kUUAppBorder            (kCommonItems + 10)
  219. #define kUUAppName                (kCommonItems + 11)
  220. #define kUUAppButton            (kCommonItems + 12)
  221.  
  222. /* Miscellaneous options topic. */
  223.  
  224. #define kReZoomWindows            (kCommonItems + 1)
  225. #define kCheckNewGroups            (kCommonItems + 2)
  226. #define kAreYouSure                (kCommonItems + 3)
  227. #define kLogActionsToFile        (kCommonItems + 4)
  228. #define kDontCoverFinderIcons    (kCommonItems + 5)
  229. #define kUseInternetConfig        (kCommonItems + 6)
  230.  
  231.  
  232.  
  233. static short gItem;                /* dialog item number hit */
  234.  
  235. static ArrowPairRef gArrowPair = nil;    /* arrow pair reference */
  236.  
  237. static Str255 gStaticText;        /* static text for signature dialog */
  238.  
  239. static short gListFontID;        /* current list font id */
  240. static short gListFontSize;        /* current list font size */
  241. static short gTextFontID;        /* current text font id */
  242. static short gTextFontSize;        /* current text font size */
  243. static short gPrintingFontID;    /* current printing font id */
  244. static short gPrintingFontSize;    /* current printing font size */
  245.  
  246. static ListHandle gURLList;        /* handle to list of URL helpers */
  247.  
  248. static Boolean gScreenFontsTopic;    /* true if screen fonts topic, false if printing font topic */
  249.  
  250. static FileFilterYDUPP gInvisibleFilesFilterUPP = nil;
  251. static UserItemUPP gDrawFontSampleUPP = nil;
  252. static UserItemUPP gDlgArrowsItemUPP = nil;
  253. static UserItemUPP gDrawURLListUPP = nil;
  254.  
  255.  
  256.  
  257. /*----------------------------------------------------------------------------
  258.     ValidHelper
  259.  
  260.     Check for a valid helper program.
  261.     
  262.     Entry:    fSpec = pointer to helper program file spec.
  263.     
  264.     Exit:    function result = true if helper is valid.
  265.             *fSpec = pointer to file spec for copy of helper program which
  266.                 will actually be used if duplicate copies of helper found.
  267. ----------------------------------------------------------------------------*/
  268.  
  269. static Boolean ValidHelper (FSSpec *fSpec)
  270. {
  271.     OSErr err = noErr;
  272.     FInfo fInfo;
  273.     FSSpec file;
  274.     CStr255 fmt, msg;
  275.  
  276.     err = FSpGetFInfo(fSpec, &fInfo);
  277.     if (err != noErr) goto exit1;
  278.     if (fInfo.fdType != 'APPL') goto exit2;
  279.     err = FindAppFromSig(fInfo.fdCreator, &file, nil, nil);
  280.     if (err == fnfErr) goto exit3;
  281.     if (err != noErr) goto exit1;
  282.     if (!IsEqualFSSpec(fSpec, &file)) goto exit4;
  283.     return true;
  284.     
  285. exit1:
  286.     
  287.     GetCString(kStrUnexpectedErr, fmt);
  288.     sprintf(msg, fmt, err);
  289.     StopAlertMessage(msg);
  290.     return false;
  291.     
  292. exit2:
  293.  
  294.     StopAlertNumber(kStrNotAnApplication);
  295.     return false;
  296.     
  297. exit3:
  298.  
  299.     StopAlertNumber(kStrDesktopDatabaseDamaged);
  300.     return true;
  301.     
  302. exit4:
  303.  
  304.     CautionAlertNumber(kStrDuplicateCopiesOfHelper);
  305.     *fSpec = file;
  306.     return true;
  307. }
  308.  
  309.  
  310.  
  311. /*----------------------------------------------------------------------------
  312.     NewsreadingOptions
  313.  
  314.     Handle the newsreading options preferences dialog.
  315.     
  316.     Entry:    prefs = pointer to new prefs.
  317.             dlg = pointer to dialog.
  318.             item = item number hit.
  319.             
  320.     Exit:    function result = false if item == kTerm and one of the 
  321.                 prefs is invalid, true otherwise.
  322. ----------------------------------------------------------------------------*/
  323.  
  324. static Boolean NewsreadingOptions (TPrefRec *prefs, DialogPtr dlg, short item)
  325. {
  326.     long maxFetch;
  327.  
  328.     switch (item) {
  329.     
  330.         case kInit:
  331.         
  332.             DlgSetCheck(dlg, kShowAuthors, prefs->showAuthors);
  333.             DlgSetCheck(dlg, kShowArtHeaders, prefs->showArtHeaders);
  334.             DlgSetCheck(dlg, kCollapseThreads, prefs->showThreadsCollapsed);
  335.             DlgSetCheck(dlg, kKeyboardShortcuts, prefs->keyboardShortcuts);
  336.             DlgSetCheck(dlg, kKeypadShortcuts, prefs->keypadShortcuts);
  337.             DlgSetCheck(dlg, kReuseArticleWinds, prefs->reuseArticleWinds);
  338.             DlgSetCheck(dlg, kReturnToSubjectWindow, prefs->returnToSubjectWindow);
  339.             DlgSetCheck(dlg, kStopAtEndOfSubjectList, prefs->stopAtEndOfSubjectList);
  340.             DlgSetCheck(dlg, kBeepAtEndOfLists, prefs->beepAtEndOfLists);
  341.             DlgSetNumber(dlg, kMaxArticles, prefs->maxFetch);
  342.             SetItemNumeric(dlg, kMaxArticles);
  343.             SetItemMaxLength(dlg, kMaxArticles, 5);
  344.             SelectDialogItemText(dlg, kMaxArticles, 0, 0x7fff);
  345.             break;
  346.             
  347.         case kTerm:
  348.             
  349.             prefs->showAuthors = DlgGetCheck(dlg, kShowAuthors);
  350.             prefs->showArtHeaders = DlgGetCheck(dlg, kShowArtHeaders);
  351.             prefs->showThreadsCollapsed = DlgGetCheck(dlg, kCollapseThreads);
  352.             prefs->keyboardShortcuts = DlgGetCheck(dlg, kKeyboardShortcuts);
  353.             prefs->keypadShortcuts = DlgGetCheck(dlg, kKeypadShortcuts);
  354.             prefs->reuseArticleWinds = DlgGetCheck(dlg, kReuseArticleWinds);
  355.             prefs->returnToSubjectWindow = DlgGetCheck(dlg, kReturnToSubjectWindow);
  356.             prefs->stopAtEndOfSubjectList = DlgGetCheck(dlg, kStopAtEndOfSubjectList);
  357.             prefs->beepAtEndOfLists = DlgGetCheck(dlg, kBeepAtEndOfLists);
  358.             maxFetch = DlgGetNumber(dlg, kMaxArticles);
  359.             if (maxFetch > 15000) maxFetch = 15000;
  360.             if (maxFetch <= 0) maxFetch = 1;
  361.             prefs->maxFetch = maxFetch;
  362.             break;
  363.             
  364.         case kShowAuthors:
  365.         case kShowArtHeaders:
  366.         case kCollapseThreads:
  367.         case kKeyboardShortcuts:
  368.         case kKeypadShortcuts:
  369.         case kReuseArticleWinds:
  370.         case kReturnToSubjectWindow:
  371.         case kStopAtEndOfSubjectList:
  372.         case kBeepAtEndOfLists:
  373.         
  374.             DlgToggleCheck(dlg, item);
  375.             break;
  376.             
  377.     }
  378.     
  379.     return true;
  380. }
  381.  
  382.  
  383.  
  384. /*----------------------------------------------------------------------------
  385.     Server
  386.  
  387.     Handles the server info preferences dialog.
  388.     
  389.     Entry:    prefs = pointer to new prefs.
  390.             dlg = pointer to dialog.
  391.             item = item number hit.
  392.             
  393.     Exit:    function result = false if item == kTerm and one of the 
  394.                 prefs is invalid, true otherwise.
  395. ----------------------------------------------------------------------------*/
  396.  
  397. static Boolean Server (TPrefRec *prefs, DialogPtr dlg, short item)
  398. {
  399.     Boolean enable;
  400.  
  401.     switch (item) {
  402.     
  403.         case kInit:
  404.         
  405.             DlgSetPString(dlg, kNewsServer, prefs->newsServerName);
  406.             SetItemHostAddress(dlg, kNewsServer);
  407.             SetItemMaxLength(dlg, kNewsServer, 255);
  408.             DlgSetPString(dlg, kMailServer, prefs->mailServerName);
  409.             SetItemHostAddress(dlg, kMailServer);
  410.             SetItemMaxLength(dlg, kMailServer, 255);
  411.             if (*prefs->newsServerName == 0) {
  412.                 SelectDialogItemText(dlg, kNewsServer, 0, 0);
  413.             } else if (*prefs->mailServerName == 0) {
  414.                 SelectDialogItemText(dlg, kMailServer, 0, 0);
  415.             } else {
  416.                 SelectDialogItemText(dlg, kNewsServer, 0, 0x7fff);
  417.             }
  418.             break;
  419.             
  420.         case kTerm:
  421.             
  422.             break;
  423.             
  424.         case kNewsServer:
  425.         case kMailServer:
  426.         
  427.             DlgGetPString(dlg, kNewsServer, prefs->newsServerName);
  428.             DlgGetPString(dlg, kMailServer, prefs->mailServerName);
  429.             enable = *prefs->newsServerName != 0 && *prefs->mailServerName != 0;
  430.             DlgEnableItem(dlg, ok, enable);
  431.             DlgEnableItem(dlg, kTopicPopup, enable);
  432.             
  433.     }
  434.     
  435.     return true;
  436. }
  437.  
  438.  
  439.  
  440. /*----------------------------------------------------------------------------
  441.     ServerOptions
  442.  
  443.     Handles the server options preferences dialog.
  444.     
  445.     Entry:    prefs = pointer to new prefs.
  446.             dlg = pointer to dialog.
  447.             item = item number hit.
  448.             
  449.     Exit:    function result = false if item == kTerm and one of the 
  450.                 prefs is invalid, true otherwise.
  451. ----------------------------------------------------------------------------*/
  452.  
  453. static Boolean ServerOptions (TPrefRec *prefs, DialogPtr dlg, short item)
  454. {
  455.     switch (item) {
  456.     
  457.         case kInit:
  458.         
  459.             DlgSetCheck(dlg, kBatchedGroupCmds, prefs->batchedGroupCmds);
  460.             DlgSetCheck(dlg, kUseXPAT, prefs->useXPAT);
  461.             DlgSetCheck(dlg, kNoNewConnection, prefs->noNewConnection);
  462.             DlgSetCheck(dlg, kNoModeReader, prefs->noModeReader);
  463.             break;
  464.             
  465.         case kTerm:
  466.             
  467.             prefs->batchedGroupCmds = DlgGetCheck(dlg, kBatchedGroupCmds);
  468.             prefs->useXPAT = DlgGetCheck(dlg, kUseXPAT);
  469.             prefs->noNewConnection = DlgGetCheck(dlg, kNoNewConnection);
  470.             prefs->noModeReader = DlgGetCheck(dlg, kNoModeReader);
  471.             break;
  472.             
  473.         case kBatchedGroupCmds:
  474.         case kUseXPAT:
  475.         case kNoNewConnection:
  476.         case kNoModeReader:
  477.         
  478.             DlgToggleCheck(dlg, item);
  479.             break;
  480.             
  481.     }
  482.     
  483.     return true;
  484. }
  485.  
  486.  
  487.  
  488. /*----------------------------------------------------------------------------
  489.     Personal
  490.  
  491.     Handles the personal info preferences dialog.
  492.     
  493.     Entry:    prefs = pointer to new prefs.
  494.             dlg = pointer to dialog.
  495.             item = item number hit.
  496.             
  497.     Exit:    function result = false if item == kTerm and one of the 
  498.                 prefs is invalid, true otherwise.
  499. ----------------------------------------------------------------------------*/
  500.  
  501. static Boolean Personal (TPrefRec *prefs, DialogPtr dlg, short item)
  502. {
  503.     switch (item) {
  504.     
  505.         case kInit:
  506.         
  507.             DlgSetCString(dlg, kFullName, prefs->fullName);
  508.             SetItemMaxLength(dlg, kFullName, 255);
  509.             DlgSetCString(dlg, kOrganization, prefs->organization);
  510.             SetItemMaxLength(dlg, kOrganization, 255);
  511.             DlgSetCString(dlg, kMailAddress, prefs->emailAddress);
  512.             SetItemUSAsciiNoBlank(dlg, kMailAddress);
  513.             SetItemMaxLength(dlg, kMailAddress, 255);
  514.             if (*prefs->fullName == 0) {
  515.                 SelectDialogItemText(dlg, kFullName, 0, 0);
  516.             } else if (*prefs->organization == 0) {
  517.                 SelectDialogItemText(dlg, kOrganization, 0, 0);
  518.             } else if (*prefs->emailAddress == 0) {
  519.                 SelectDialogItemText(dlg, kMailAddress, 0, 0);
  520.             } else {
  521.                 SelectDialogItemText(dlg, kFullName, 0, 0x7fff);
  522.             }
  523.             break;
  524.             
  525.         case kTerm:
  526.             
  527.             if (gItem != cancel && !StringIsValidEmailAddress(prefs->emailAddress)) {
  528.                 StopAlertNumber(kStrBadEmailAddress);
  529.                 return false;
  530.             }
  531.             DlgGetCString(dlg, kFullName, prefs->fullName);
  532.             DlgGetCString(dlg, kOrganization, prefs->organization);
  533.             break;
  534.             
  535.         case kMailAddress:
  536.         
  537.             DlgGetCString(dlg, kMailAddress, prefs->emailAddress);
  538.             DlgEnableItem(dlg, ok, *prefs->emailAddress != 0);
  539.             DlgEnableItem(dlg, kTopicPopup, *prefs->emailAddress != 0);
  540.             
  541.     }
  542.     
  543.     return true;
  544. }
  545.  
  546.  
  547.  
  548. /*----------------------------------------------------------------------------
  549.     Signature
  550.  
  551.     Handles the signature preferences dialog.
  552.     
  553.     Entry:    prefs = pointer to new prefs.
  554.             dlg = pointer to dialog.
  555.             item = item number hit.
  556.             
  557.     Exit:    function result = false if item == kTerm and one of the 
  558.                 prefs is invalid, true otherwise.
  559. ----------------------------------------------------------------------------*/
  560.  
  561. static Boolean Signature (TPrefRec *prefs, DialogPtr dlg, short item)
  562. {
  563.     short len;
  564.  
  565.     switch (item) {
  566.     
  567.         case kInit:
  568.         
  569.             DlgSetCheck(dlg, kAddSigBlankLine, prefs->addSigBlankLine);
  570.             DlgSetCheck(dlg, kAddSigSeparator, prefs->addSigSeparatorLine);
  571.             SetItemScrollingTextField(dlg, kSignatureEditText, 
  572.                 prefs->textFont, prefs->textSize, false);
  573.             DlgSetScrollingText(dlg, kSignatureEditText, prefs->signature,
  574.                 strlen(prefs->signature));
  575.             DlgSetScrollingTextSelection(dlg, kSignatureEditText, 0, 0);
  576.             SetItemMaxLength(dlg, kSignatureEditText, 4095);
  577.             break;
  578.             
  579.         case kTerm:
  580.             
  581.             prefs->addSigBlankLine = DlgGetCheck(dlg, kAddSigBlankLine);
  582.             prefs->addSigSeparatorLine = DlgGetCheck(dlg, kAddSigSeparator);
  583.             DlgGetScrollingText(dlg, kSignatureEditText, prefs->signature, &len);
  584.             prefs->signature[len] = 0;
  585.             break;
  586.             
  587.         case kAddSigBlankLine:
  588.         case kAddSigSeparator:
  589.         
  590.             DlgToggleCheck(dlg, item);
  591.             break;
  592.             
  593.     }
  594.     
  595.     return true;
  596. }
  597.  
  598.  
  599.  
  600. /*----------------------------------------------------------------------------
  601.     MessageOptions
  602.  
  603.     Handles the message options preferences dialog.
  604.     
  605.     Entry:    prefs = pointer to new prefs.
  606.             dlg = pointer to dialog.
  607.             item = item number hit.
  608.             
  609.     Exit:    function result = false if item == kTerm and one of the 
  610.                 prefs is invalid, true otherwise.
  611. ----------------------------------------------------------------------------*/
  612.  
  613. static Boolean MessageOptions (TPrefRec *prefs, DialogPtr dlg, short item)
  614. {
  615.  
  616.     switch (item) {
  617.     
  618.         case kInit:
  619.         
  620.             DlgSetCheck(dlg, kMsgReplyPost, prefs->replyPost);
  621.             DlgSetCheck(dlg, kMsgReplyEmail, prefs->replyEmail);
  622.             DlgSetCheck(dlg, kMsgCopySelf, prefs->copySelf);
  623.             DlgSetCheck(dlg, kMsgShowMsgDetails, prefs->showMsgDetails);
  624.             DlgSetCheck(dlg, kMsgWrapOnSend, prefs->wrapOnSend);
  625.             DlgSetCheck(dlg, kMsgShowLabels, prefs->showLabelsUnderIcons);
  626.             DlgSetCheck(dlg, kMsgTabEnabled, prefs->tabEnabled);
  627.             DlgSetNumber(dlg, kMsgTabStops, prefs->tabStops);
  628.             SetItemNumeric(dlg, kMsgTabStops);
  629.             SetItemMaxLength(dlg, kMsgTabStops, 2);
  630.             SelectDialogItemText(dlg, kMsgTabStops, 0, 0x7fff);
  631.             DlgSetCString(dlg, kMsgQuoteString, prefs->quoteString);
  632.             SetItemMaxLength(dlg, kMsgQuoteString, 10);
  633.             break;
  634.             
  635.         case kTerm:
  636.             
  637.             prefs->replyPost = DlgGetCheck(dlg, kMsgReplyPost);
  638.             prefs->replyEmail = DlgGetCheck(dlg, kMsgReplyEmail);
  639.             prefs->copySelf = DlgGetCheck(dlg, kMsgCopySelf);
  640.             prefs->showMsgDetails = DlgGetCheck(dlg, kMsgShowMsgDetails);
  641.             prefs->wrapOnSend = DlgGetCheck(dlg, kMsgWrapOnSend);
  642.             prefs->showLabelsUnderIcons = DlgGetCheck(dlg, kMsgShowLabels);
  643.             prefs->tabEnabled = DlgGetCheck(dlg, kMsgTabEnabled);
  644.             prefs->tabStops = DlgGetNumber(dlg, kMsgTabStops);
  645.             DlgGetCString(dlg, kMsgQuoteString, prefs->quoteString);
  646.               break;
  647.             
  648.         case kMsgReplyPost:
  649.         case kMsgReplyEmail:
  650.         case kMsgCopySelf:
  651.         case kMsgShowMsgDetails:
  652.         case kMsgWrapOnSend:
  653.         case kMsgShowLabels:
  654.         case kMsgTabEnabled:
  655.         
  656.             DlgToggleCheck(dlg, item);
  657.             break;
  658.             
  659.     }
  660.     
  661.     return true;
  662. }
  663.  
  664.  
  665.  
  666. /*----------------------------------------------------------------------------
  667.     ExtraHeaderLines
  668.  
  669.     Handles the extra header lines preferences dialog.
  670.     
  671.     Entry:    prefs = pointer to new prefs.
  672.             dlg = pointer to dialog.
  673.             item = item number hit.
  674.             
  675.     Exit:    function result = false if item == kTerm and one of the 
  676.                 prefs is invalid, true otherwise.
  677. ----------------------------------------------------------------------------*/
  678.  
  679. static Boolean ExtraHeaderLines (TPrefRec *prefs, DialogPtr dlg, short item)
  680. {
  681.     short len;
  682.  
  683.     switch (item) {
  684.     
  685.         case kInit:
  686.         
  687.             SetItemScrollingTextField(dlg, kMsgExtraNewsHdrLines, 
  688.                 prefs->textFont, prefs->textSize, false);
  689.             DlgSetScrollingText(dlg, kMsgExtraNewsHdrLines, prefs->extraNewsHdrLines,
  690.                 strlen(prefs->extraNewsHdrLines));
  691.             SetItemMaxLength(dlg, kMsgExtraNewsHdrLines, 255);
  692.             SetItemScrollingTextField(dlg, kMsgExtraMailHdrLines, 
  693.                 prefs->textFont, prefs->textSize, false);
  694.             DlgSetScrollingText(dlg, kMsgExtraMailHdrLines, prefs->extraMailHdrLines,
  695.                 strlen(prefs->extraMailHdrLines));
  696.             SetItemMaxLength(dlg, kMsgExtraMailHdrLines, 255);
  697.             DlgSetScrollingTextSelection(dlg, kMsgExtraNewsHdrLines, 0, 0);
  698.             break;
  699.             
  700.         case kTerm:
  701.             
  702.             DlgGetScrollingText(dlg, kMsgExtraNewsHdrLines, prefs->extraNewsHdrLines, &len);
  703.             prefs->extraNewsHdrLines[len] = 0;
  704.             DlgGetScrollingText(dlg, kMsgExtraMailHdrLines, prefs->extraMailHdrLines, &len);
  705.             prefs->extraMailHdrLines[len] = 0;
  706.               break;
  707.             
  708.     }
  709.     
  710.     return true;
  711. }
  712.  
  713.  
  714.  
  715. /*----------------------------------------------------------------------------
  716.     Remote
  717.  
  718.     Handles the remote host info preferences dialog.
  719.     
  720.     Entry:    prefs = pointer to new prefs.
  721.             dlg = pointer to dialog.
  722.             item = item number hit.
  723.             
  724.     Exit:    function result = false if item == kTerm and one of the 
  725.                 prefs is invalid, true otherwise.
  726. ----------------------------------------------------------------------------*/
  727.  
  728. static Boolean Remote (TPrefRec *prefs, DialogPtr dlg, short item)
  729. {
  730.     CStr255 tempStr;
  731.     short len;
  732.  
  733.     switch (item) {
  734.     
  735.         case kInit:
  736.         
  737.             DlgSetCString(dlg, kRemoteHostAddr, prefs->ftpNewsrcHost);
  738.             SetItemHostAddress(dlg, kRemoteHostAddr);
  739.             SetItemMaxLength(dlg, kRemoteHostAddr, 255);
  740.             DlgSetCString(dlg, kRemoteLogin, prefs->ftpNewsrcUsername);
  741.             SetItemUSAsciiNoBlank(dlg, kRemoteLogin);
  742.             SetItemMaxLength(dlg, kRemoteLogin, 255);
  743.             len = strlen(prefs->ftpNewsrcPassword);
  744.             memset(tempStr, '•', len);
  745.             tempStr[len] = 0;
  746.             DlgSetCString(dlg, kRemotePassword, tempStr);
  747.             SetItemPassword(dlg, kRemotePassword, prefs->ftpNewsrcPassword);
  748.             SetItemMaxLength(dlg, kRemotePassword, 31);
  749.             DlgSetCString(dlg, kRemotePath, prefs->ftpNewsrcPath);
  750.             SetItemMaxLength(dlg, kRemotePath, 31);
  751.             DlgSetCheck(dlg, kAutoGetPut, prefs->autoFetchNewsrc);
  752.             DlgSetCheck(dlg, kSavePassword, prefs->saveFtpNewsrcPassword);
  753.             if (*prefs->ftpNewsrcHost == 0) {
  754.                 SelectDialogItemText(dlg, kRemoteHostAddr, 0, 0);
  755.             } else if (*prefs->ftpNewsrcUsername == 0) {
  756.                 SelectDialogItemText(dlg, kRemoteLogin, 0, 0);
  757.             } else if (*prefs->ftpNewsrcPassword == 0) {
  758.                 SelectDialogItemText(dlg, kRemotePassword, 0, 0);
  759.             } else if (*prefs->ftpNewsrcPath == 0) {
  760.                 SelectDialogItemText(dlg, kRemotePath, 0, 0);
  761.             } else {
  762.                 SelectDialogItemText(dlg, kRemoteHostAddr, 0, 0x7fff);
  763.             }
  764.             break;
  765.             
  766.         case kTerm:
  767.             
  768.             DlgGetCString(dlg, kRemoteHostAddr, prefs->ftpNewsrcHost);
  769.             DlgGetCString(dlg, kRemoteLogin, prefs->ftpNewsrcUsername);
  770.             DlgGetCString(dlg, kRemotePath, prefs->ftpNewsrcPath);
  771.             prefs->autoFetchNewsrc = DlgGetCheck(dlg, kAutoGetPut);
  772.             prefs->saveFtpNewsrcPassword = DlgGetCheck(dlg, kSavePassword);
  773.             break;
  774.         
  775.         case kSavePassword:
  776.         case kAutoGetPut:
  777.         
  778.             DlgToggleCheck(dlg, item);
  779.             break;
  780.             
  781.     }
  782.     
  783.     return true;
  784. }
  785.  
  786.  
  787.  
  788. /*----------------------------------------------------------------------------
  789.     DrawFontSample
  790.     
  791.     A user item procedure to draw the font samples.
  792.     
  793.     Entry:    dlg = pointer to dialog.
  794.             item = item number.
  795. ----------------------------------------------------------------------------*/
  796.  
  797. static pascal void DrawFontSample (DialogPtr dlg, short item)
  798. {
  799.     short itemType;
  800.     Rect box;
  801.     Handle itemHandle;
  802.     Str255 text;
  803.     short fontID, fontSize;
  804.     TextStyle savedStyle;
  805.  
  806.     DlgGrayBorderItem(dlg, item);
  807.     GetDialogItem(dlg, item, &itemType, &itemHandle, &box);
  808.     if (gScreenFontsTopic) {
  809.         if (item == kListSample) {
  810.             GetPString(kStrGroupSubjectSample, text);
  811.             fontID = gListFontID;
  812.             fontSize = gListFontSize;
  813.         } else {
  814.             GetPString(kStrArtMsgSample, text);
  815.             fontID = gTextFontID;
  816.             fontSize = gTextFontSize;
  817.         }
  818.     } else {
  819.         GetPString(kStrPrintingSample, text);
  820.         fontID = gPrintingFontID;
  821.         fontSize = gPrintingFontSize;
  822.     }
  823.     GetPortTextStyle(&savedStyle);
  824.     TextFont(fontID);
  825.     TextSize(fontSize);
  826.     InsetRect(&box, 2, 2);
  827.     TETextBox(text + 1, *text, &box, teFlushDefault);
  828.     SetPortTextStyle(&savedStyle);
  829. }
  830.  
  831.  
  832.  
  833. /*----------------------------------------------------------------------------
  834.     RedrawSample
  835.  
  836.     Force one of the sample text items to be redrawn.
  837.     
  838.     Entry:    dlg = pointer to dialog.
  839.             item = item number.
  840. ----------------------------------------------------------------------------*/
  841.  
  842. static void RedrawSample (DialogPtr dlg, short item)
  843. {
  844.     short itemType;
  845.     Handle itemHandle;
  846.     Rect box;
  847.     
  848.     GetDialogItem(dlg, item, &itemType, &itemHandle, &box);
  849.     InsetRect(&box, 2, 2);
  850.     EraseRect(&box);
  851.     InvalRect(&box);
  852. }
  853.  
  854.  
  855.  
  856. /*----------------------------------------------------------------------------
  857.     SetNewFont
  858.  
  859.     Set a new font in the font/size dialog.
  860.     
  861.     Entry:    dlg = pointer to dialog.
  862.             listFont = true if list font, false if text font.
  863.             fontNum = new font number.
  864. ----------------------------------------------------------------------------*/
  865.  
  866. static void SetNewFont (DialogPtr dlg, Boolean listFont, short fontNum)
  867. {
  868.     short numItems, i;
  869.     Str255 itemStr, fontName;
  870.     ControlHandle ctl;
  871.     long size;
  872.  
  873.     /* Select the right font in the font popup menu. */
  874.     
  875.     ctl = DlgGetControl(dlg, 
  876.         gScreenFontsTopic ? (listFont ? kListFontPopup : kTextFontPopup) : kPrintingFontPopup);
  877.     GetFontName(fontNum, fontName);
  878.     SetPopupValue(ctl, fontName, false);
  879.     
  880.     /* Adjust the size popup so the nice sizes are outlined. */
  881.  
  882.     ctl = DlgGetControl(dlg, 
  883.         gScreenFontsTopic ? (listFont ? kListSizePopup : kTextSizePopup) : kPrintingSizePopup);
  884.     numItems = GetControlMaximum(ctl);
  885.     for (i = 1; i <= numItems; i++) {
  886.         GetPopupPString(ctl, i, itemStr);
  887.         StringToNum(itemStr, &size);
  888.         if (RealFont(fontNum, (short)size)) {
  889.             SetPopupItemStyle(ctl, i, outline);
  890.         } else {
  891.             SetPopupItemStyle(ctl, i, 0);
  892.         }
  893.     }
  894.  
  895.     /* Force the sample text to be redrawn */
  896.     
  897.     RedrawSample(dlg, 
  898.         gScreenFontsTopic ? (listFont ? kListSample : kTextSample) : kPrintingSample);
  899. }
  900.  
  901.  
  902.  
  903. /*----------------------------------------------------------------------------
  904.     FontIDFromPopup
  905.  
  906.     Get the font ID corresponding the currently selected font in a popup menu.
  907.     
  908.     Entry:    dlg = pointer to dialog.
  909.             item = item number of popup menu.
  910. ----------------------------------------------------------------------------*/
  911.  
  912. static short FontIDFromPopup (DialogPtr dlg, short item)
  913. {
  914.     ControlHandle ctl;
  915.     short fontNum;
  916.     Str255 fontName;
  917.  
  918.     ctl = DlgGetControl(dlg, item);
  919.     GetPopupPString(ctl, kCurrentPopupItem, fontName);
  920.     GetFontNumber(fontName, &fontNum);
  921.     return fontNum;
  922. }
  923.  
  924.  
  925.  
  926. /*----------------------------------------------------------------------------
  927.     ScreenFonts
  928.  
  929.     Handles the screen fonts preferences dialog.
  930.     
  931.     Entry:    prefs = pointer to new prefs.
  932.             dlg = pointer to dialog.
  933.             item = item number hit.
  934.             
  935.     Exit:    function result = false if item == kTerm and one of the 
  936.                 prefs is invalid, true otherwise.
  937. ----------------------------------------------------------------------------*/
  938.  
  939. static Boolean ScreenFonts (TPrefRec *prefs, DialogPtr dlg, short item)
  940. {
  941.     Str255 tempStr;
  942.     long num;
  943.  
  944.     switch (item) {
  945.     
  946.         case kInit:
  947.         
  948.             gScreenFontsTopic = true;
  949.             GetFontNumber(prefs->listFont, &gListFontID);
  950.             gListFontSize = prefs->listSize;
  951.             SetNewFont(dlg, true, gListFontID);
  952.             DlgSetNumber(dlg, kListSizeBox, gListFontSize);
  953.             SetItemNumeric(dlg, kListSizeBox);
  954.             SetItemMaxLength(dlg, kListSizeBox, 2);
  955.             SelectDialogItemText(dlg, kListSizeBox, 0, 0x7fff);
  956.             SetItemPopupTypeinItem(dlg, kListSizePopup, kListSizeBox);
  957.             
  958.             GetFontNumber(prefs->textFont, &gTextFontID);
  959.             gTextFontSize = prefs->textSize;
  960.             SetNewFont(dlg, false, gTextFontID);
  961.             DlgSetNumber(dlg, kTextSizeBox, gTextFontSize);
  962.             SetItemNumeric(dlg, kTextSizeBox);
  963.             SetItemMaxLength(dlg, kTextSizeBox, 2);
  964.             SetItemPopupTypeinItem(dlg, kTextSizePopup, kTextSizeBox);
  965.             
  966.               DlgSetUserItem(dlg, kListSample, gDrawFontSampleUPP);
  967.               DlgSetUserItem(dlg, kTextSample, gDrawFontSampleUPP);
  968.               DlgSetUserItem(dlg, kListVertLine, gDlgGrayBorderItemUPP);
  969.             break;
  970.             
  971.         case kTerm:
  972.             
  973.               GetFontName(gListFontID, prefs->listFont);
  974.               GetFontName(gTextFontID, prefs->textFont);
  975.               prefs->listSize = gListFontSize;
  976.               prefs->textSize = gTextFontSize;
  977.             break;
  978.             
  979.         case kListFontPopup:
  980.         
  981.               gListFontID = FontIDFromPopup(dlg, item);
  982.               SetNewFont(dlg, true, gListFontID);
  983.             break;
  984.             
  985.         case kTextFontPopup:
  986.         
  987.               gTextFontID = FontIDFromPopup(dlg, item);
  988.               SetNewFont(dlg, false, gTextFontID);
  989.             break;            
  990.           
  991.         case kListSizePopup:
  992.         case kListSizeBox:
  993.         
  994.               DlgGetPString(dlg, kListSizeBox, tempStr);
  995.               StringToNum(tempStr, &num);
  996.               if (num != 0 && num != gListFontSize) {
  997.                   gListFontSize = num;
  998.                   RedrawSample(dlg, kListSample);
  999.               }
  1000.             break;
  1001.           
  1002.         case kTextSizePopup:
  1003.         case kTextSizeBox:
  1004.         
  1005.               DlgGetPString(dlg, kTextSizeBox, tempStr);
  1006.               StringToNum(tempStr, &num);
  1007.               if (num != 0 && num != gTextFontSize) {
  1008.                   gTextFontSize = num;
  1009.                   RedrawSample(dlg, kTextSample);
  1010.               }
  1011.             break;
  1012.             
  1013.     }
  1014.     
  1015.     return true;
  1016. }
  1017.  
  1018.  
  1019.  
  1020. /*----------------------------------------------------------------------------
  1021.     PrintingFont
  1022.  
  1023.     Handles the printing font preferences dialog.
  1024.     
  1025.     Entry:    prefs = pointer to new prefs.
  1026.             dlg = pointer to dialog.
  1027.             item = item number hit.
  1028.             
  1029.     Exit:    function result = false if item == kTerm and one of the 
  1030.                 prefs is invalid, true otherwise.
  1031. ----------------------------------------------------------------------------*/
  1032.  
  1033. static Boolean PrintingFont (TPrefRec *prefs, DialogPtr dlg, short item)
  1034. {
  1035.     Str255 tempStr;
  1036.     long num;
  1037.  
  1038.     switch (item) {
  1039.     
  1040.         case kInit:
  1041.         
  1042.             gScreenFontsTopic = false;
  1043.             GetFontNumber(prefs->printingFont, &gPrintingFontID);
  1044.             gPrintingFontSize = prefs->printingSize;
  1045.             SetNewFont(dlg, true, gPrintingFontID);
  1046.             DlgSetNumber(dlg, kPrintingSizeBox, gPrintingFontSize);
  1047.             SetItemNumeric(dlg, kPrintingSizeBox);
  1048.             SetItemMaxLength(dlg, kPrintingSizeBox, 2);
  1049.             SelectDialogItemText(dlg, kPrintingSizeBox, 0, 0x7fff);
  1050.             SetItemPopupTypeinItem(dlg, kPrintingSizePopup, kPrintingSizeBox);
  1051.               DlgSetUserItem(dlg, kPrintingSample, gDrawFontSampleUPP);
  1052.             break;
  1053.             
  1054.         case kTerm:
  1055.             
  1056.               GetFontName(gPrintingFontID, prefs->printingFont);
  1057.               prefs->printingSize = gPrintingFontSize;
  1058.             break;
  1059.             
  1060.         case kPrintingFontPopup:
  1061.         
  1062.               gPrintingFontID = FontIDFromPopup(dlg, item);
  1063.               SetNewFont(dlg, true, gPrintingFontID);
  1064.             break;
  1065.           
  1066.         case kPrintingSizePopup:
  1067.         case kPrintingSizeBox:
  1068.         
  1069.               DlgGetPString(dlg, kPrintingSizeBox, tempStr);
  1070.               StringToNum(tempStr, &num);
  1071.               if (num != 0 && num != gPrintingFontSize) {
  1072.                   gPrintingFontSize = num;
  1073.                   RedrawSample(dlg, kPrintingSample);
  1074.               }
  1075.             break;
  1076.             
  1077.     }
  1078.     
  1079.     return true;
  1080. }
  1081.  
  1082.  
  1083.  
  1084. /*----------------------------------------------------------------------------
  1085.     SavedUGL
  1086.  
  1087.     Handles the saved user group lists preferences dialog.
  1088.     
  1089.     Entry:    prefs = pointer to new prefs.
  1090.             dlg = pointer to dialog.
  1091.             item = item number hit.
  1092.             
  1093.     Exit:    function result = false if item == kTerm and one of the 
  1094.                 prefs is invalid, true otherwise.
  1095. ----------------------------------------------------------------------------*/
  1096.  
  1097. static Boolean SavedUGL (TPrefRec *prefs, DialogPtr dlg, short item)
  1098. {
  1099.     StandardFileReply reply;
  1100.     long dirID;
  1101.     Str31 name;
  1102.     OSErr err = noErr;
  1103.     CInfoPBRec pb;
  1104.     Boolean valid;
  1105.     AliasHandle alias;
  1106.  
  1107.     switch (item) {
  1108.     
  1109.         case kInit:
  1110.  
  1111.             DlgSetCheck(dlg, kSavedUGLDirCheckBox, prefs->savedUGLDefaultFolder);
  1112.               DlgSetUserItem(dlg, kSavedUGLDirBorder, gDlgGrayBorderItemUPP);            
  1113.             ValidateSavedFolderAlias(prefs->savedUGLDefaultFolderAlias,
  1114.                 &pb.dirInfo.ioVRefNum, &pb.dirInfo.ioDrDirID, &valid);
  1115.               if (valid) {
  1116.                 pb.dirInfo.ioNamePtr = name;
  1117.                 pb.dirInfo.ioFDirIndex = -1;
  1118.                 err = PBGetCatInfo(&pb, false);
  1119.             } else {
  1120.                *name = 0;
  1121.             }
  1122.             DlgSetPString(dlg, kSavedUGLDirName, name);
  1123.             DlgEnableItem(dlg, kSavedUGLDirButton, prefs->savedUGLDefaultFolder);
  1124.             DlgSetCheck(dlg, kSavedUGLAutoSaveOnQuit, prefs->autoSaveOnQuit);
  1125.                 
  1126.             break;
  1127.             
  1128.         case kTerm:
  1129.         
  1130.             prefs->autoSaveOnQuit = DlgGetCheck(dlg, kSavedUGLAutoSaveOnQuit);
  1131.             break;
  1132.             
  1133.         case kSavedUGLDirCheckBox:
  1134.         
  1135.             DlgToggleCheck(dlg, item);
  1136.             prefs->savedUGLDefaultFolder = DlgGetCheck(dlg, item);
  1137.             DlgEnableItem(dlg, kSavedUGLDirButton, prefs->savedUGLDefaultFolder);
  1138.             break;
  1139.             
  1140.         case kSavedUGLDirButton:
  1141.         
  1142.             MyStandardGetDirectory(&reply, &dirID);
  1143.             if (!reply.sfGood) break;
  1144.             err = NewAlias(nil, &reply.sfFile, &alias);
  1145.             if (err == noErr) {
  1146.                 MyDisposeHandle(prefs->savedUGLDefaultFolderAlias);
  1147.                 prefs->savedUGLDefaultFolderAlias = alias;
  1148.             }
  1149.             DlgSetPString(dlg, kSavedUGLDirName, reply.sfFile.name);
  1150.             break;
  1151.             
  1152.         case kSavedUGLAutoSaveOnQuit:
  1153.         
  1154.             DlgToggleCheck(dlg, item);
  1155.             break;
  1156.             
  1157.     }
  1158.     
  1159.     return true;
  1160. }
  1161.  
  1162.  
  1163.  
  1164. /*----------------------------------------------------------------------------
  1165.     InvisibleFilesFilter
  1166.  
  1167.     A standard file dialog filter to filter out invisible files.
  1168.     
  1169.     Entry:    pb = pointer to file info param block.
  1170.             myDataPtr = pointer to private data (not used).
  1171.             
  1172.     Exit:    function result = true if file is invisible.
  1173. ----------------------------------------------------------------------------*/
  1174.  
  1175. static pascal Boolean InvisibleFilesFilter (CInfoPBPtr pb, void *myDataPtr)
  1176. {
  1177.     return (pb->hFileInfo.ioFlFndrInfo.fdFlags & fInvisible) != 0;
  1178. }
  1179.  
  1180.  
  1181.  
  1182. /*----------------------------------------------------------------------------
  1183.     SavedArt
  1184.  
  1185.     Handles the saved articles preferences dialog.
  1186.     
  1187.     Entry:    prefs = pointer to new prefs.
  1188.             dlg = pointer to dialog.
  1189.             item = item number hit.
  1190.             
  1191.     Exit:    function result = false if item == kTerm and one of the 
  1192.                 prefs is invalid, true otherwise.
  1193. ----------------------------------------------------------------------------*/
  1194.  
  1195. static Boolean SavedArt (TPrefRec *prefs, DialogPtr dlg, short item)
  1196. {
  1197.     StandardFileReply reply;
  1198.     FInfo fInfo;
  1199.     long dirID;
  1200.     Str31 name;
  1201.     OSErr err = noErr;
  1202.     CInfoPBRec pb;
  1203.     Boolean valid;
  1204.     AliasHandle alias;
  1205.  
  1206.     switch (item) {
  1207.     
  1208.         case kInit:
  1209.  
  1210.               DlgSetUserItem(dlg, kSavedArtAppBorder, gDlgGrayBorderItemUPP);
  1211.               err = FindAppNameFromSig(prefs->savedArtCreator, name);
  1212.               if (err == noErr) {
  1213.                   DlgSetPString(dlg, kSavedArtAppName, name);
  1214.                   CopyPascalString(prefs->savedArtAppName, name);
  1215.               } else {
  1216.                 DlgSetPString(dlg, kSavedArtAppName, prefs->savedArtAppName);
  1217.             }
  1218.             DlgSetCheck(dlg, kSavedArtDirCheckBox, prefs->savedArtDefaultFolder);
  1219.               DlgSetUserItem(dlg, kSavedArtDirBorder, gDlgGrayBorderItemUPP);            
  1220.             ValidateSavedFolderAlias(prefs->savedArtDefaultFolderAlias,
  1221.                 &pb.dirInfo.ioVRefNum, &pb.dirInfo.ioDrDirID, &valid);
  1222.               if (valid) {
  1223.                 pb.dirInfo.ioNamePtr = name;
  1224.                 pb.dirInfo.ioFDirIndex = -1;
  1225.                 err = PBGetCatInfo(&pb, false);
  1226.             } else {
  1227.                *name = 0;
  1228.             }
  1229.             DlgSetPString(dlg, kSavedArtDirName, name);
  1230.             DlgEnableItem(dlg, kSavedArtDirButton, prefs->savedArtDefaultFolder);
  1231.             DlgSetCheck(dlg, kSavedArtSepFiles, prefs->saveThreadsToSeparateFiles);
  1232.             DlgSetCheck(dlg, kSavedArtAutoAppend, prefs->appendIfFileAlreadyExists);
  1233.             DlgSetCheck(dlg, kSavedArtSaveEncoded, prefs->saveEncodedText);
  1234.                 
  1235.             break;
  1236.             
  1237.         case kTerm:
  1238.         
  1239.             prefs->saveThreadsToSeparateFiles = DlgGetCheck(dlg, kSavedArtSepFiles);
  1240.             prefs->appendIfFileAlreadyExists = DlgGetCheck(dlg, kSavedArtAutoAppend);
  1241.             prefs->saveEncodedText = DlgGetCheck(dlg, kSavedArtSaveEncoded);
  1242.             break;
  1243.             
  1244.         case kSavedArtAppButton:
  1245.         
  1246.             MyStandardGetFile(gInvisibleFilesFilterUPP, 2, "APPLadrp", &reply, nil);
  1247.             if (!reply.sfGood) break;
  1248.             FSpGetFInfo(&reply.sfFile, &fInfo);
  1249.             prefs->savedArtCreator = fInfo.fdCreator;
  1250.             CopyPascalString(prefs->savedArtAppName, reply.sfFile.name);
  1251.             DlgSetPString(dlg, kSavedArtAppName, prefs->savedArtAppName);
  1252.             break;
  1253.             
  1254.         case kSavedArtDirCheckBox:
  1255.         
  1256.             DlgToggleCheck(dlg, item);
  1257.             prefs->savedArtDefaultFolder = DlgGetCheck(dlg, item);
  1258.             DlgEnableItem(dlg, kSavedArtDirButton, prefs->savedArtDefaultFolder);
  1259.             break;
  1260.             
  1261.         case kSavedArtDirButton:
  1262.         
  1263.             MyStandardGetDirectory(&reply, &dirID);
  1264.             if (!reply.sfGood) break;
  1265.             err = NewAlias(nil, &reply.sfFile, &alias);
  1266.             if (err == noErr) {
  1267.                 MyDisposeHandle(prefs->savedArtDefaultFolderAlias);
  1268.                 prefs->savedArtDefaultFolderAlias = alias;
  1269.             }
  1270.             DlgSetPString(dlg, kSavedArtDirName, reply.sfFile.name);
  1271.             break;
  1272.             
  1273.         case kSavedArtSepFiles:
  1274.         case kSavedArtAutoAppend:
  1275.         case kSavedArtSaveEncoded:
  1276.         
  1277.             DlgToggleCheck(dlg, item);
  1278.             break;
  1279.             
  1280.     }
  1281.     
  1282.     return true;
  1283. }
  1284.  
  1285.  
  1286.  
  1287. /*----------------------------------------------------------------------------
  1288.     SavedMsg
  1289.  
  1290.     Handles the saved messages preferences dialog.
  1291.     
  1292.     Entry:    prefs = pointer to new prefs.
  1293.             dlg = pointer to dialog.
  1294.             item = item number hit.
  1295.             
  1296.     Exit:    function result = false if item == kTerm and one of the 
  1297.                 prefs is invalid, true otherwise.
  1298. ----------------------------------------------------------------------------*/
  1299.  
  1300. static Boolean SavedMsg (TPrefRec *prefs, DialogPtr dlg, short item)
  1301. {
  1302.     StandardFileReply reply;
  1303.     long dirID;
  1304.     Str31 name;
  1305.     OSErr err = noErr;
  1306.     CInfoPBRec pb;
  1307.     Boolean valid;
  1308.     AliasHandle alias;
  1309.  
  1310.     switch (item) {
  1311.     
  1312.         case kInit:
  1313.  
  1314.             DlgSetCheck(dlg, kSavedMsgDirCheckBox, prefs->savedMsgDefaultFolder);
  1315.               DlgSetUserItem(dlg, kSavedMsgDirBorder, gDlgGrayBorderItemUPP);            
  1316.             ValidateSavedFolderAlias(prefs->savedMsgDefaultFolderAlias,
  1317.                 &pb.dirInfo.ioVRefNum, &pb.dirInfo.ioDrDirID, &valid);
  1318.               if (valid) {
  1319.                 pb.dirInfo.ioNamePtr = name;
  1320.                 pb.dirInfo.ioFDirIndex = -1;
  1321.                 err = PBGetCatInfo(&pb, false);
  1322.             } else {
  1323.                 *name = 0;
  1324.             }
  1325.             DlgSetPString(dlg, kSavedMsgDirName, name);
  1326.             DlgEnableItem(dlg, kSavedMsgDirButton, prefs->savedMsgDefaultFolder);
  1327.             DlgSetCheck(dlg, kSavedMsgDelAfterSend, prefs->savedMsgDelAfterSend);
  1328.                 
  1329.             break;
  1330.             
  1331.         case kTerm:
  1332.         
  1333.             break;
  1334.             
  1335.         case kSavedMsgDirCheckBox:
  1336.         
  1337.             DlgToggleCheck(dlg, item);
  1338.             prefs->savedMsgDefaultFolder = DlgGetCheck(dlg, item);
  1339.             DlgEnableItem(dlg, kSavedMsgDirButton, prefs->savedMsgDefaultFolder);
  1340.             break;
  1341.             
  1342.         case kSavedMsgDirButton:
  1343.         
  1344.             MyStandardGetDirectory(&reply, &dirID);
  1345.             if (!reply.sfGood) break;
  1346.             err = NewAlias(nil, &reply.sfFile, &alias);
  1347.             if (err == noErr) {
  1348.                 MyDisposeHandle(prefs->savedMsgDefaultFolderAlias);
  1349.                 prefs->savedMsgDefaultFolderAlias = alias;
  1350.             }
  1351.             DlgSetPString(dlg, kSavedMsgDirName, reply.sfFile.name);
  1352.             break;
  1353.             
  1354.         case kSavedMsgDelAfterSend:
  1355.         
  1356.             DlgToggleCheck(dlg, item);
  1357.             prefs->savedMsgDelAfterSend = DlgGetCheck(dlg, item);
  1358.             break;
  1359.             
  1360.     }
  1361.     
  1362.     return true;
  1363. }
  1364.  
  1365.  
  1366.  
  1367. /*----------------------------------------------------------------------------
  1368.     DrawURLList
  1369.     
  1370.     A user item procedure to draw the URL helper list.
  1371.     
  1372.     Entry:    dlg = pointer to dialog.
  1373.             item = item number.
  1374. ----------------------------------------------------------------------------*/
  1375.  
  1376. static pascal void DrawURLList (DialogPtr dlg, short item)
  1377. {
  1378.     short itemType;
  1379.     Rect box;
  1380.     Handle itemHandle;
  1381.  
  1382.     GetDialogItem(dlg, item, &itemType, &itemHandle, &box);
  1383.     FrameRect(&box);
  1384.     LUpdate(dlg->visRgn, gURLList);
  1385. }
  1386.  
  1387.  
  1388.  
  1389. /*----------------------------------------------------------------------------
  1390.     SetNewURLHelper
  1391.  
  1392.     Set a new URL helper.
  1393.     
  1394.     Entry:    prefs = pointer to new prefs.
  1395. ----------------------------------------------------------------------------*/
  1396.  
  1397. static void SetNewURLHelper (TPrefRec *prefs)
  1398. {
  1399.     Point cell;
  1400.     TURLHelperInfo *p;
  1401.     char appName[32];
  1402.     CStr255 str;
  1403.     short i;
  1404.     StandardFileReply reply;
  1405.  
  1406.     i = GetFirstSelectedCell(gURLList);
  1407.     if (i < 0) return;
  1408.     MyStandardGetFile(gInvisibleFilesFilterUPP, 2, "APPLadrp", &reply, nil);
  1409.     if (!reply.sfGood) return;
  1410.     if (!ValidHelper(&reply.sfFile)) return;
  1411.     MyHLock(prefs->urlHelpers);
  1412.     p = &(*prefs->urlHelpers)[i];
  1413.     if (ValidURLHelper(&reply.sfFile, p)) {
  1414.         SetPt(&cell, 0, i);
  1415.         *appName = 0;
  1416.         if (p->sig != 0) FindAppNameFromSig(p->sig, (StringPtr)appName);
  1417.         p2cstr((StringPtr)appName);
  1418.         sprintf(str, "%s — %s", p->schemeName, appName);
  1419.         LSetCell(str, strlen(str), cell, gURLList);
  1420.     }
  1421.     MyHUnlock(prefs->urlHelpers);
  1422. }
  1423.  
  1424.  
  1425.  
  1426. /*----------------------------------------------------------------------------
  1427.     AdjustURLButtons
  1428.  
  1429.     Adjust (enable/disable) the Change, Delete, and Add buttons in the URL
  1430.     helper programs topic.
  1431.     
  1432.     Entry:    dlg = pointer to dialog.
  1433. ----------------------------------------------------------------------------*/
  1434.  
  1435. static void AdjustURLButtons (DialogPtr dlg)
  1436. {
  1437.     short i;
  1438.     TURLSchemeName schemeName;
  1439.     
  1440.     i = GetFirstSelectedCell(gURLList);
  1441.     DlgEnableItem(dlg, kURLChangeButton, i >= 0);
  1442.     DlgEnableItem(dlg, kURLDeleteButton, i >= 0);
  1443.     DlgGetCString(dlg, kURLNewScheme, schemeName);
  1444.     DlgEnableItem(dlg, kURLAddButton, *schemeName != 0);
  1445. }
  1446.  
  1447.  
  1448.  
  1449. /*----------------------------------------------------------------------------
  1450.     CompareURLHelperInfo
  1451.  
  1452.     Compare two URL helper program info records.
  1453.     
  1454.     Entry:    a = pointer to first helper program info record.
  1455.             b = pointer to second helper program info record.
  1456.             
  1457.     Exit:    function result = 
  1458.                 -1 if a->schemeName < b->schemName
  1459.                 0  if a->schemeName = b->schemName
  1460.                 +1 if a->schemeName > b->schemName
  1461. ----------------------------------------------------------------------------*/
  1462.  
  1463. static OSErr CompareURLHelperInfo (TURLHelperInfo *a, TURLHelperInfo *b, short *result)
  1464. {
  1465.     *result = MyStrCmp(a->schemeName, b->schemeName);
  1466.     return noErr;
  1467. }
  1468.  
  1469.  
  1470. /*----------------------------------------------------------------------------
  1471.     URLScrollIntoView
  1472.     
  1473.     Scroll the selected cell into view in the URL topic.
  1474. ----------------------------------------------------------------------------*/
  1475.  
  1476. static void URLScrollIntoView (void)
  1477. {
  1478.     Cell cell;
  1479.     short top, bot;
  1480.     
  1481.     cell.h = 0;
  1482.     cell.v = GetFirstSelectedCell(gURLList);
  1483.     if (cell.v < 0) return;
  1484.     top = (**gURLList).visible.top;
  1485.     bot = (**gURLList).visible.bottom;
  1486.     if (cell.v < top) {
  1487.         LScroll(0, cell.v - top, gURLList);
  1488.     } else if (cell.v >= bot) {
  1489.         LScroll(0, cell.v - bot + 1, gURLList);
  1490.     }
  1491. }
  1492.  
  1493.  
  1494. /*----------------------------------------------------------------------------
  1495.     URLHelpersFilter
  1496.     
  1497.     Filter proc for the URL Helper Programs topic.
  1498.         
  1499.     Entry:    dlg = pointer to dialog.
  1500.             ev = pointer to event record.
  1501.             
  1502.     Exit:    function result = true if event handled and item hit.
  1503.             *itemHit = item number of item hit.
  1504.             ev = pointer to possibly modified event record.
  1505.             
  1506.     This dialog filter handles the up and down arrow keys.
  1507. ----------------------------------------------------------------------------*/
  1508.  
  1509. static pascal Boolean URLHelpersFilter (DialogPtr dlg, EventRecord *ev, 
  1510.     short *itemHit)
  1511. {
  1512.     unsigned char theChar;
  1513.     Cell cell;
  1514.     short numCells;
  1515.  
  1516.     if (ev->what == keyDown || ev->what == autoKey) {
  1517.         theChar = ev->message & charCodeMask;
  1518.         if (theChar == upArrow || theChar == downArrow) {
  1519.             numCells = (**gURLList).dataBounds.bottom;
  1520.             if (numCells > 0) {
  1521.                 cell.h = 0;
  1522.                 cell.v = GetFirstSelectedCell(gURLList);
  1523.                 if (cell.v == -1 && theChar == upArrow) cell.v = numCells;
  1524.                 if (theChar == downArrow) {
  1525.                     cell.v++;
  1526.                 } else {
  1527.                     cell.v--;
  1528.                 }
  1529.                 if (cell.v < 0) {
  1530.                     cell.v = 0;
  1531.                 } else if (cell.v >= numCells) {
  1532.                     cell.v = numCells - 1;
  1533.                 }
  1534.                 SelectSingleListItem(gURLList, cell);
  1535.                 URLScrollIntoView();
  1536.             } 
  1537.             AdjustURLButtons(dlg);
  1538.             ev->what = nullEvent;
  1539.             return false;
  1540.         }
  1541.     }
  1542.     return DialogFilter(dlg, ev, itemHit);
  1543. }
  1544.  
  1545.  
  1546.  
  1547. /*----------------------------------------------------------------------------
  1548.     URLHelpers
  1549.  
  1550.     Handles the URL helper programs preferences dialog.
  1551.     
  1552.     Entry:    prefs = pointer to new prefs.
  1553.             dlg = pointer to dialog.
  1554.             item = item number hit.
  1555.             
  1556.     Exit:    function result = false if item == kTerm and one of the 
  1557.                 prefs is invalid, true otherwise.
  1558. ----------------------------------------------------------------------------*/
  1559.  
  1560. static Boolean URLHelpers (TPrefRec *prefs, DialogPtr dlg, short item)
  1561. {
  1562.     short itemType;
  1563.     Rect box;
  1564.     Handle itemHandle;
  1565.     Rect dataBounds;
  1566.     Point cSize, cell, where;
  1567.     TURLHelperInfo *p;
  1568.     short numHelpers;
  1569.     char appName[32];
  1570.     CStr255 str, fmt, msg;
  1571.     short i;
  1572.     long len;
  1573.     TURLSchemeName schemeName;
  1574.     char *c;
  1575.     short cmp;
  1576.     TURLHelperInfo newHelper;
  1577.     OSErr err = noErr;
  1578.     StandardFileReply reply;
  1579.  
  1580.     switch (item) {
  1581.     
  1582.         case kInit:
  1583.             
  1584.             GetDialogItem(dlg, kURLList, &itemType, &itemHandle, &box);
  1585.             InsetRect(&box, 1, 1);
  1586.             box.right -= 15;
  1587.             numHelpers = 0;
  1588.             for (p = *prefs->urlHelpers; *p->schemeName != 0; p++) numHelpers++;
  1589.             SetRect(&dataBounds, 0, 0, 1, numHelpers);
  1590.             SetPt(&cSize, 0, 0);
  1591.             gURLList = LNew(&box, &dataBounds, cSize, 0, dlg, false, false, false, true);
  1592.             (**gURLList).selFlags = lOnlyOne;
  1593.             SetPt(&cell, 0, 0);
  1594.             MyHLock(prefs->urlHelpers);
  1595.             FastQSort(*prefs->urlHelpers, numHelpers, sizeof(TURLHelperInfo), 
  1596.                 CompareURLHelperInfo);
  1597.             for (p = *prefs->urlHelpers; *p->schemeName != 0; p++) {
  1598.                 *appName = 0;
  1599.                 if (p->sig != 0) FindAppNameFromSig(p->sig, (StringPtr)appName);
  1600.                 p2cstr((StringPtr)appName);
  1601.                 sprintf(str, "%s — %s", p->schemeName, appName);
  1602.                 LSetCell(str, strlen(str), cell, gURLList);
  1603.                 cell.v++;
  1604.             }
  1605.             MyHUnlock(prefs->urlHelpers); 
  1606.             SetPt(&cell, 0, 0);
  1607.             LSetSelect(true, cell, gURLList);
  1608.             LSetDrawingMode(true, gURLList);
  1609.               DlgSetUserItem(dlg, kURLList, gDrawURLListUPP);
  1610.             SetItemURLSchemeName(dlg, kURLNewScheme);
  1611.             SetItemMaxLength(dlg, kURLNewScheme, kMaxSchemeNameLen);
  1612.             DlgSetCheck(dlg, kURLUseWebHelper, prefs->useWebHelperForHtmlFiles);
  1613.             AdjustURLButtons(dlg);
  1614.             break;
  1615.             
  1616.         case kTerm:
  1617.         
  1618.             prefs->useWebHelperForHtmlFiles = DlgGetCheck(dlg, kURLUseWebHelper);
  1619.             LDispose(gURLList);
  1620.             break;
  1621.             
  1622.         case kURLList:
  1623.         
  1624.             where = gCurEvent.where;
  1625.             GlobalToLocal(&where);
  1626.             GetDialogItem(dlg, kURLList, &itemType, &itemHandle, &box);
  1627.             InsetRect(&box, 1, 2);
  1628.             if (PtInRect(where, &box)) {
  1629.                 if (LClick(where, gCurEvent.modifiers, gURLList))
  1630.                     SetNewURLHelper(prefs);
  1631.             }
  1632.             AdjustURLButtons(dlg);
  1633.             break;
  1634.             
  1635.         case kURLChangeButton:
  1636.         
  1637.             SetNewURLHelper(prefs);
  1638.             break;
  1639.             
  1640.         case kURLDeleteButton:
  1641.         
  1642.             i = GetFirstSelectedCell(gURLList);
  1643.             if (i < 0) break;
  1644.             len = MyGetHandleSize(prefs->urlHelpers);
  1645.             BlockMoveData(
  1646.                 *prefs->urlHelpers + i + 1,
  1647.                 *prefs->urlHelpers + i,
  1648.                 len - (i+1) * sizeof(TURLHelperInfo));
  1649.             MySetHandleSize(prefs->urlHelpers, len - sizeof(TURLHelperInfo));
  1650.             LDelRow(1, i, gURLList);
  1651.             if (i >= (**gURLList).dataBounds.bottom) i--;
  1652.             if (i >= 0) {
  1653.                 SetPt(&cell, 0, i);
  1654.                 SelectSingleListItem(gURLList, cell);
  1655.                 URLScrollIntoView();
  1656.             }
  1657.             AdjustURLButtons(dlg);
  1658.             break;
  1659.             
  1660.         case kURLNewScheme:
  1661.         
  1662.             AdjustURLButtons(dlg);
  1663.             break;
  1664.             
  1665.         case kURLAddButton:
  1666.         
  1667.             DlgGetCString(dlg, kURLNewScheme, schemeName);
  1668.             if (*schemeName == 0) break;
  1669.             for (c = schemeName; *c != 0; c++) *c = tolower(*c);
  1670.             if (MyStrCmp(schemeName, "nntp") == 0 || MyStrCmp(schemeName, "news") == 0 ||
  1671.                 MyStrCmp(schemeName, "mailto") == 0) 
  1672.             {
  1673.                 StopAlertNumber(kStrCantRedefineBuiltinURLs);
  1674.                 return true;
  1675.             }
  1676.             for (i = 0, p = *prefs->urlHelpers; *p->schemeName != 0; i++, p++) {
  1677.                 cmp = MyStrCmp(schemeName, p->schemeName);
  1678.                 if (cmp < 0) break;
  1679.                 if (cmp == 0) {
  1680.                     SetPt(&cell, 0, i);
  1681.                     SelectSingleListItem(gURLList, cell);
  1682.                     MyLScrollCellIntoView(cell, gURLList);
  1683.                     GetCString(kStrURLSchemeAlreadyDefined, fmt);
  1684.                     sprintf(msg, fmt, schemeName);
  1685.                     StopAlertMessage(msg);
  1686.                     return true;
  1687.                 }
  1688.             }
  1689.             MyStandardGetFile(gInvisibleFilesFilterUPP, 2, "APPLadrp", &reply, nil);
  1690.             if (!reply.sfGood) return true;
  1691.             if (!ValidHelper(&reply.sfFile)) return true;
  1692.             if (ValidURLHelper(&reply.sfFile, &newHelper)) {
  1693.                 len = MyGetHandleSize(prefs->urlHelpers);
  1694.                 err = MySetHandleSize(prefs->urlHelpers, len + sizeof(TURLHelperInfo));
  1695.                 if (err != noErr) {
  1696.                     StopAlertNumber(kStrOutOfMemory);
  1697.                     return true;
  1698.                 }
  1699.                 BlockMoveData(
  1700.                     *prefs->urlHelpers + i,
  1701.                     *prefs->urlHelpers + i + 1,
  1702.                     len - i * sizeof(TURLHelperInfo));
  1703.                 strcpy(newHelper.schemeName, schemeName);
  1704.                 (*prefs->urlHelpers)[i] = newHelper;
  1705.                 LAddRow(1, i, gURLList);
  1706.                 SetPt(&cell, 0, i);
  1707.                 *appName = 0;
  1708.                 if (newHelper.sig != 0) FindAppNameFromSig(newHelper.sig, (StringPtr)appName);
  1709.                 p2cstr((StringPtr)appName);
  1710.                 sprintf(str, "%s — %s", schemeName, appName);
  1711.                 LSetCell(str, strlen(str), cell, gURLList);
  1712.                 SelectSingleListItem(gURLList, cell);
  1713.                 MyLScrollCellIntoView(cell, gURLList);
  1714.                 DlgSetCString(dlg, kURLNewScheme, "");
  1715.                 AdjustURLButtons(dlg);
  1716.             }
  1717.             break;
  1718.         
  1719.         case kURLUseWebHelper:
  1720.         
  1721.             DlgToggleCheck(dlg, item);
  1722.             break;
  1723.     }
  1724.     
  1725.     return true;
  1726. }
  1727.  
  1728.  
  1729.  
  1730. /*----------------------------------------------------------------------------
  1731.     Auth
  1732.  
  1733.     Handles the authorization preferences dialog.
  1734.     
  1735.     Entry:    prefs = pointer to new prefs.
  1736.             dlg = pointer to dialog.
  1737.             item = item number hit.
  1738.             
  1739.     Exit:    function result = false if item == kTerm and one of the 
  1740.                 prefs is invalid, true otherwise.
  1741. ----------------------------------------------------------------------------*/
  1742.  
  1743. static Boolean Auth (TPrefRec *prefs, DialogPtr dlg, short item)
  1744. {
  1745.     CStr255 tempStr;
  1746.     short len;
  1747.  
  1748.     switch (item) {
  1749.     
  1750.         case kInit:
  1751.  
  1752.             DlgSetCString(dlg, kAuthUsername, prefs->authUsername);
  1753.             SetItemUSAsciiNoBlank(dlg, kAuthUsername);
  1754.             SetItemMaxLength(dlg, kAuthUsername, 31);
  1755.             len = strlen(prefs->authPassword);
  1756.             memset(tempStr, '•', len);
  1757.             tempStr[len] = 0;
  1758.             DlgSetCString(dlg, kAuthPassword, tempStr);
  1759.             SetItemPassword(dlg, kAuthPassword, prefs->authPassword);
  1760.             SetItemMaxLength(dlg, kAuthPassword, 31);
  1761.             DlgSetCheck(dlg, kAuthSavePassword, prefs->authSavePassword);
  1762.             DlgSetCheck(dlg, kAuthPrivateGroups, prefs->authPrivateGroups);
  1763.             DlgSetCtlValue(dlg, prefs->authAtStartup ? kAuthAtStartup : 
  1764.                 kAuthWhenRequested, 1);
  1765.             if (*prefs->authUsername == 0) {
  1766.                 SelectDialogItemText(dlg, kAuthUsername, 0, 0);
  1767.             } else if (*prefs->authPassword == 0) {
  1768.                 SelectDialogItemText(dlg, kAuthPassword, 0, 0);
  1769.             } else {
  1770.                 SelectDialogItemText(dlg, kAuthUsername, 0, 0x7fff);
  1771.             }
  1772.             break;
  1773.             
  1774.         case kTerm:
  1775.             
  1776.             DlgGetCString(dlg, kAuthUsername, prefs->authUsername);
  1777.             prefs->authSavePassword = DlgGetCheck(dlg, kAuthSavePassword);
  1778.             prefs->authPrivateGroups = DlgGetCheck(dlg, kAuthPrivateGroups);
  1779.             prefs->authAtStartup = DlgGetCtlValue(dlg, kAuthAtStartup) == 1;
  1780.             break;
  1781.         
  1782.         case kAuthSavePassword:
  1783.         case kAuthPrivateGroups:
  1784.         
  1785.             DlgToggleCheck(dlg, item);
  1786.             break;
  1787.         
  1788.         case kAuthAtStartup:
  1789.         
  1790.             if (DlgGetCtlValue(dlg, kAuthAtStartup) == 0) {
  1791.                 DlgSetCtlValue(dlg, kAuthAtStartup, 1);
  1792.                 DlgSetCtlValue(dlg, kAuthWhenRequested, 0);
  1793.             }
  1794.             break;
  1795.             
  1796.         case kAuthWhenRequested:
  1797.         
  1798.             if (DlgGetCtlValue(dlg, kAuthWhenRequested) == 0) {
  1799.                 DlgSetCtlValue(dlg, kAuthWhenRequested, 1);
  1800.                 DlgSetCtlValue(dlg, kAuthAtStartup, 0);
  1801.             }
  1802.             break;
  1803.             
  1804.     }
  1805.     
  1806.     return true;
  1807. }
  1808.  
  1809.  
  1810.  
  1811. /*----------------------------------------------------------------------------
  1812.     Extract
  1813.  
  1814.     Handles the extracting binaries preferences dialog.
  1815.     
  1816.     Entry:    prefs = pointer to new prefs.
  1817.             dlg = pointer to dialog.
  1818.             item = item number hit.
  1819.             
  1820.     Exit:    function result = false if item == kTerm and one of the 
  1821.                 prefs is invalid, true otherwise.
  1822. ----------------------------------------------------------------------------*/
  1823.  
  1824. static Boolean Extract (TPrefRec *prefs, DialogPtr dlg, short item)
  1825. {
  1826.     StandardFileReply reply;
  1827.     FInfo fInfo;
  1828.     long dirID;
  1829.     Str31 name;
  1830.     OSErr err = noErr;
  1831.     CInfoPBRec pb;
  1832.     Boolean valid;
  1833.     AliasHandle alias;
  1834.  
  1835.     switch (item) {
  1836.     
  1837.         case kInit:
  1838.  
  1839.             DlgSetCheck(dlg, kSavedBinDirCheckBox, prefs->savedBinDefaultFolder);
  1840.               DlgSetUserItem(dlg, kSavedBinDirBorder, gDlgGrayBorderItemUPP);            
  1841.             ValidateSavedFolderAlias(prefs->savedBinDefaultFolderAlias,
  1842.                 &pb.dirInfo.ioVRefNum, &pb.dirInfo.ioDrDirID, &valid);
  1843.               if (valid) {
  1844.                 pb.dirInfo.ioNamePtr = name;
  1845.                 pb.dirInfo.ioFDirIndex = -1;
  1846.                 err = PBGetCatInfo(&pb, false);
  1847.             } else {
  1848.                 *name = 0;
  1849.             }
  1850.             DlgSetPString(dlg, kSavedBinDirName, name);
  1851.             DlgEnableItem(dlg, kSavedBinDirButton, prefs->savedBinDefaultFolder);
  1852.             
  1853.               DlgSetUserItem(dlg, kHqxAppBorder, gDlgGrayBorderItemUPP);
  1854.               err = FindAppNameFromSig(prefs->hqxHelper, name);
  1855.               if (err == noErr) {
  1856.                   DlgSetPString(dlg, kHqxAppName, name);
  1857.                   CopyPascalString(prefs->hqxHelperName, name);
  1858.               } else {
  1859.                 DlgSetPString(dlg, kHqxAppName, prefs->hqxHelperName);
  1860.             }
  1861.             
  1862.               DlgSetUserItem(dlg, kUUAppBorder, gDlgGrayBorderItemUPP);
  1863.               err = FindAppNameFromSig(prefs->uuHelper, name);
  1864.               if (err == noErr) {
  1865.                   DlgSetPString(dlg, kUUAppName, name);
  1866.                   CopyPascalString(prefs->uuHelperName, name);
  1867.               } else {
  1868.                 DlgSetPString(dlg, kUUAppName, prefs->uuHelperName);
  1869.             }
  1870.                 
  1871.             break;
  1872.             
  1873.         case kTerm:
  1874.         
  1875.             break;
  1876.             
  1877.         case kSavedBinDirCheckBox:
  1878.         
  1879.             DlgToggleCheck(dlg, item);
  1880.             prefs->savedBinDefaultFolder = DlgGetCheck(dlg, item);
  1881.             DlgEnableItem(dlg, kSavedBinDirButton, prefs->savedBinDefaultFolder);
  1882.             break;
  1883.             
  1884.         case kSavedBinDirButton:
  1885.         
  1886.             MyStandardGetDirectory(&reply, &dirID);
  1887.             if (!reply.sfGood) break;
  1888.             err = NewAlias(nil, &reply.sfFile, &alias);
  1889.             if (err == noErr) {
  1890.                 MyDisposeHandle(prefs->savedBinDefaultFolderAlias);
  1891.                 prefs->savedBinDefaultFolderAlias = alias;
  1892.             }
  1893.             DlgSetPString(dlg, kSavedBinDirName, reply.sfFile.name);
  1894.             break;
  1895.             
  1896.         case kHqxAppButton:
  1897.         
  1898.             MyStandardGetFile(gInvisibleFilesFilterUPP, 2, "APPLadrp", &reply, nil);
  1899.             if (!reply.sfGood) break;
  1900.             if (!ValidHelper(&reply.sfFile)) break;
  1901.             FSpGetFInfo(&reply.sfFile, &fInfo);
  1902.             prefs->hqxHelper = fInfo.fdCreator;
  1903.             CopyPascalString(prefs->hqxHelperName, reply.sfFile.name);
  1904.             DlgSetPString(dlg, kHqxAppName, prefs->hqxHelperName);
  1905.             break;            
  1906.             
  1907.         case kUUAppButton:
  1908.         
  1909.             MyStandardGetFile(gInvisibleFilesFilterUPP, 2, "APPLadrp", &reply, nil);
  1910.             if (!reply.sfGood) break;
  1911.             if (!ValidHelper(&reply.sfFile)) break;
  1912.             FSpGetFInfo(&reply.sfFile, &fInfo);
  1913.             prefs->uuHelper = fInfo.fdCreator;
  1914.             CopyPascalString(prefs->uuHelperName, reply.sfFile.name);
  1915.             DlgSetPString(dlg, kUUAppName, prefs->uuHelperName);
  1916.             break;            
  1917.             
  1918.     }
  1919.     
  1920.     return true;
  1921. }
  1922.  
  1923.  
  1924.  
  1925. /*----------------------------------------------------------------------------
  1926.     MiscOptions
  1927.  
  1928.     Handle the miscellaneous options preferences dialog.
  1929.     
  1930.     Entry:    prefs = pointer to new prefs.
  1931.             dlg = pointer to dialog.
  1932.             item = item number hit.
  1933.             
  1934.     Exit:    function result = false if item == kTerm and one of the 
  1935.                 prefs is invalid, true otherwise.
  1936. ----------------------------------------------------------------------------*/
  1937.  
  1938. static Boolean MiscOptions (TPrefRec *prefs, DialogPtr dlg, short item)
  1939. {
  1940.     switch (item) {
  1941.     
  1942.         case kInit:
  1943.         
  1944.             DlgSetCheck(dlg, kReZoomWindows, prefs->reZoomWindows);
  1945.             DlgSetCheck(dlg, kCheckNewGroups, prefs->checkForNewGroups);
  1946.             DlgSetCheck(dlg, kAreYouSure, prefs->areYouSureAlert);
  1947.             DlgSetCheck(dlg, kLogActionsToFile, prefs->logActionsToFile);
  1948.             DlgSetCheck(dlg, kDontCoverFinderIcons, prefs->dontCoverFinderIcons);
  1949.             DlgSetCheck(dlg, kUseInternetConfig, prefs->useInternetConfig);
  1950.             break;
  1951.             
  1952.         case kTerm:
  1953.             
  1954.             prefs->reZoomWindows = DlgGetCheck(dlg, kReZoomWindows);
  1955.             prefs->checkForNewGroups = DlgGetCheck(dlg, kCheckNewGroups);
  1956.             prefs->areYouSureAlert = DlgGetCheck(dlg, kAreYouSure);
  1957.             prefs->logActionsToFile = DlgGetCheck(dlg, kLogActionsToFile);
  1958.             prefs->dontCoverFinderIcons = DlgGetCheck(dlg, kDontCoverFinderIcons);
  1959.             prefs->useInternetConfig = DlgGetCheck(dlg, kUseInternetConfig);
  1960.             break;
  1961.             
  1962.         case kReZoomWindows:
  1963.         case kCheckNewGroups:
  1964.         case kAreYouSure:
  1965.         case kLogActionsToFile:
  1966.         case kDontCoverFinderIcons:
  1967.         case kUseInternetConfig:
  1968.         
  1969.             DlgToggleCheck(dlg, item);
  1970.             break;
  1971.             
  1972.     }
  1973.     
  1974.     return true;
  1975. }
  1976.  
  1977.  
  1978.  
  1979. /*----------------------------------------------------------------------------
  1980.     DrawGrayOutline
  1981.  
  1982.     A user item procedure to draw the gray outline.
  1983.     
  1984.     Entry:    dlg = pointer to dialog.
  1985.             item = item number of gray outline user item.
  1986. ----------------------------------------------------------------------------*/
  1987.  
  1988. static pascal void DrawGrayOutline (DialogPtr dlg, short item)
  1989. {
  1990.     Handle itemHandle;
  1991.     ControlHandle popupCtl;
  1992.     short itemType;
  1993.     Rect box, popupBox, r;
  1994.  
  1995.     GetDialogItem(dlg, item, &itemType, &itemHandle, &box);
  1996.     GetDialogItem(dlg, kTopicPopup, &itemType, (Handle*)&popupCtl, &popupBox);
  1997.     popupBox = (**popupCtl).contrlRect;
  1998.     r = box;
  1999.     r.bottom = r.top + 1;
  2000.     r.right = popupBox.left - 1;
  2001.     DrawGrayRect(&r);
  2002.     r = box;
  2003.     r.bottom = r.top + 1;
  2004.     r.left = popupBox.right + 5;
  2005.     DrawGrayRect(&r);
  2006.     r = box;
  2007.     r.right = r.left + 1;
  2008.     DrawGrayRect(&r);
  2009.     r = box;
  2010.     r.left = r.right - 1;
  2011.     DrawGrayRect(&r);
  2012.     r = box;
  2013.     r.top = r.bottom - 1;
  2014.     DrawGrayRect(&r);
  2015. }
  2016.  
  2017.  
  2018.  
  2019. /*----------------------------------------------------------------------------
  2020.     DrawArrows
  2021.     
  2022.     A user item procedure to draw the arrows.
  2023.     
  2024.     Entry:    dlg = pointer to dialog.
  2025.             item = item number.
  2026. ----------------------------------------------------------------------------*/
  2027.  
  2028. static pascal void DrawArrows (DialogPtr dlg, short item)
  2029. {
  2030.     short itemType;
  2031.     Handle itemHandle;
  2032.     Rect box;
  2033.  
  2034.     GetDialogItem(dlg, kArrows, &itemType, &itemHandle, &box);
  2035.     FrameRoundRect(&box, 8, 8);
  2036.     DrawArrowPair(gArrowPair);
  2037. }
  2038.  
  2039.  
  2040.  
  2041. /*----------------------------------------------------------------------------
  2042.     TrackArrowClick
  2043.     
  2044.     Track a click on the arrows user item.
  2045.     
  2046.     Entry:    dlg = pointer to dialog.
  2047.             curTopic = current topic number.
  2048.             
  2049.     Exit:    function result = new topic number.
  2050. ----------------------------------------------------------------------------*/
  2051.  
  2052. static short TrackArrowClick (DialogPtr dlg, short curTopic)
  2053. {
  2054.     short itemType;
  2055.     Rect box;
  2056.     Handle itemHandle;
  2057.     short delta;
  2058.     short newTopic;
  2059.  
  2060.     delta = TrackArrowPair(gArrowPair);
  2061.     newTopic = curTopic + delta;
  2062.     if (newTopic < 1) newTopic = 1;
  2063.     if (newTopic > kNumTopics) newTopic = kNumTopics;
  2064.     if (newTopic != curTopic) {
  2065.         GetDialogItem(dlg, kTopicPopup, &itemType, &itemHandle, &box);
  2066.         SetControlValue((ControlHandle)itemHandle, newTopic);
  2067.     }
  2068.     return newTopic;
  2069. }
  2070.  
  2071.  
  2072.  
  2073. /*----------------------------------------------------------------------------
  2074.     DoPreferences
  2075.  
  2076.     Presents the Preferences dialog.
  2077.     
  2078.     Exit:    function result = error code.
  2079. ----------------------------------------------------------------------------*/
  2080.  
  2081. OSErr DoPreferences (void)
  2082. {
  2083.     typedef Boolean (*prefsFuncPtr) (TPrefRec *prefs, DialogPtr dlg, short item);
  2084.     
  2085.     static prefsFuncPtr prefsFuncPtrs[] = {
  2086.         NewsreadingOptions,
  2087.         Server,
  2088.         ServerOptions,
  2089.         Personal,
  2090.         Signature,
  2091.         MessageOptions,
  2092.         ExtraHeaderLines,
  2093.         Remote,
  2094.         ScreenFonts,
  2095.         PrintingFont,
  2096.         SavedUGL,
  2097.         SavedArt,
  2098.         SavedMsg,
  2099.         URLHelpers,
  2100.         Auth,
  2101.         Extract,
  2102.         MiscOptions,
  2103.     };
  2104.  
  2105.     static short curTopic = kNewsreadingOptions;
  2106.     
  2107.     short newTopic;
  2108.     prefsFuncPtr theFunc;
  2109.     TPrefRec *prefs = nil;
  2110.     DialogPtr dlg = nil;
  2111.     Boolean reauthenticate = false;
  2112.     Handle theDITL;
  2113.     Point newLocn;
  2114.     OSErr err = noErr;
  2115.     GrafPtr port;
  2116.     Boolean valid;
  2117.     short itemType;
  2118.     Handle itemHandle;
  2119.     Rect box, arrowRect, backwardHotRect, forwardHotRect;
  2120.     
  2121.     GetPort(&port);
  2122.     
  2123.     MyICReadSharedPrefs(kICAllSharedPrefs);
  2124.     err = MyNewPtr(sizeof(TPrefRec), &prefs);
  2125.     if (err != noErr) goto exit;
  2126.     *prefs = gPrefs;
  2127.     if (prefs->savedMsgDefaultFolderAlias != nil) {
  2128.         err = MyHandToHand(&prefs->savedMsgDefaultFolderAlias);
  2129.         if (err != noErr) {
  2130.             prefs->savedMsgDefaultFolderAlias = nil;
  2131.             prefs->savedArtDefaultFolderAlias = nil;
  2132.             prefs->savedBinDefaultFolderAlias = nil;
  2133.             prefs->savedUGLDefaultFolderAlias = nil;
  2134.             goto exit;
  2135.         }
  2136.     }
  2137.     if (prefs->savedArtDefaultFolderAlias != nil) {
  2138.         err = MyHandToHand(&prefs->savedArtDefaultFolderAlias);
  2139.         if (err != noErr) {
  2140.             prefs->savedArtDefaultFolderAlias = nil;
  2141.             prefs->savedBinDefaultFolderAlias = nil;
  2142.             prefs->savedUGLDefaultFolderAlias = nil;
  2143.             goto exit;
  2144.         }
  2145.     }
  2146.     if (prefs->savedBinDefaultFolderAlias != nil) {
  2147.         err = MyHandToHand(&prefs->savedBinDefaultFolderAlias);
  2148.         if (err != noErr) {
  2149.             prefs->savedBinDefaultFolderAlias = nil;
  2150.             prefs->savedUGLDefaultFolderAlias = nil;
  2151.             goto exit;
  2152.         }
  2153.     }
  2154.     if (prefs->savedUGLDefaultFolderAlias != nil) {
  2155.         err = MyHandToHand(&prefs->savedUGLDefaultFolderAlias);
  2156.         if (err != noErr) {
  2157.             prefs->savedUGLDefaultFolderAlias = nil;
  2158.             goto exit;
  2159.         }
  2160.     }
  2161.     if (prefs->urlHelpers != nil) {
  2162.         err = MyHandToHand(&prefs->urlHelpers);
  2163.         if (err != noErr) {
  2164.             prefs->urlHelpers = nil;
  2165.             goto exit;
  2166.         }
  2167.     }
  2168.  
  2169.     err = MyGetNewDialog(kPrefsDlg, ok, cancel, &dlg);
  2170.     if (err != noErr) goto exit;
  2171.     SetPort(dlg);
  2172.     RestoreMovableModalDialogPosition(dlg, gPrefs.prefsLoc);
  2173.     
  2174.     GetDialogItem(dlg, kArrows, &itemType, &itemHandle, &box);
  2175.     SetRect(&arrowRect, box.left + 2, box.top + 3, box.left + 12, box.top + 21);
  2176.     backwardHotRect = forwardHotRect = box;
  2177.     backwardHotRect.bottom = forwardHotRect.top = box.top + 13;
  2178.     backwardHotRect.top++;
  2179.     forwardHotRect.bottom++;
  2180.     err = CreateArrowPair(true, &arrowRect, &backwardHotRect,
  2181.         &forwardHotRect, &gArrowPair);
  2182.     if (err != noErr) goto exit;
  2183.     EnableOrDisableArrowPair(gArrowPair, -1, curTopic > 1);
  2184.     EnableOrDisableArrowPair(gArrowPair, +1, curTopic < kNumTopics);
  2185.     
  2186.     for (gItem = kFirstGrayLine; gItem <= kLastGrayLine; gItem++)
  2187.         DlgSetUserItem(dlg, gItem, gDlgGrayBorderItemUPP);
  2188.     DlgSetUserItem(dlg, kArrows, gDlgArrowsItemUPP);
  2189.     if (curTopic == kScreenFonts || curTopic == kPrintingFont) SetCursor(&gWatchCurs);
  2190.     err = MyGetResource('DITL', kPrefsDlg + curTopic, &theDITL);
  2191.     if (err == noErr) err = MyAppendDITL(dlg, theDITL, overlayDITL);
  2192.     InitCursor();
  2193.     if (err != noErr) goto exit;
  2194.     MyReleaseResource(theDITL);
  2195.     DlgSetCtlValue(dlg, kTopicPopup, curTopic);
  2196.     theFunc = prefsFuncPtrs[curTopic - 1];
  2197.     (*theFunc)(prefs, dlg, kInit);
  2198.     DlgSetDefaultButtonOutline(dlg, curTopic != kSignature && curTopic != kExtraHeaderLines);
  2199.     
  2200.     while (true) {
  2201.         MyMovableModalDialog(dlg, 
  2202.             curTopic == kURLHelpers ? URLHelpersFilter : DialogFilter, 
  2203.             &gItem);
  2204.         if (gItem == ok || gItem == cancel) {
  2205.             valid = (*theFunc)(prefs, dlg, kTerm);
  2206.             if (valid || gItem == cancel) break;
  2207.         } else if (gItem == kTopicPopup || gItem == kArrows) {
  2208.             if (gItem == kTopicPopup) {
  2209.                 newTopic = DlgGetCtlValue(dlg, kTopicPopup);
  2210.             } else {
  2211.                 newTopic = TrackArrowClick(dlg, curTopic);
  2212.             }
  2213.             if (newTopic != curTopic) {
  2214.                 valid = (*theFunc)(prefs, dlg, kTerm);
  2215.                 if (valid) {
  2216.                     curTopic = newTopic;
  2217.                     EnableOrDisableArrowPair(gArrowPair, -1, curTopic > 1);
  2218.                     EnableOrDisableArrowPair(gArrowPair, +1, curTopic < kNumTopics);
  2219.                     MyShortenDITL(dlg, CountDITL(dlg) - kCommonItems);
  2220.                     if (curTopic == kScreenFonts || curTopic == kPrintingFont) SetCursor(&gWatchCurs);
  2221.                     err = MyGetResource('DITL', kPrefsDlg + curTopic, &theDITL);
  2222.                     if (err == noErr) err = MyAppendDITL(dlg, theDITL, overlayDITL);
  2223.                     InitCursor();
  2224.                     if (err != noErr) goto exit;
  2225.                     MyReleaseResource(theDITL);
  2226.                     theFunc = prefsFuncPtrs[curTopic - 1];
  2227.                     (*theFunc)(prefs, dlg, kInit);
  2228.                     DlgSetDefaultButtonOutline(dlg, 
  2229.                         curTopic != kSignature && curTopic != kExtraHeaderLines);
  2230.                 } else {
  2231.                     GetDialogItem(dlg, kTopicPopup, &itemType, &itemHandle, &box);
  2232.                     SetControlValue((ControlHandle)itemHandle, curTopic);
  2233.                 }    
  2234.             }
  2235.         } else {
  2236.             (*theFunc)(prefs, dlg, gItem);
  2237.         }
  2238.     }
  2239.     
  2240.     SaveMovableModalDialogPosition(dlg, &newLocn);
  2241.     
  2242.     DisposeArrowPair(gArrowPair);
  2243.     gArrowPair = nil;
  2244.     
  2245.     err = DoClose(dlg);
  2246.     dlg = nil;
  2247.     if (err != noErr) goto exit;
  2248.     
  2249.     if (gItem == ok) {
  2250.         if (prefs->logActionsToFile && !gPrefs.logActionsToFile) {
  2251.             OpenLogFile();
  2252.         } else if (!prefs->logActionsToFile && gPrefs.logActionsToFile) {
  2253.             CloseLogFile();
  2254.         }
  2255.         if (!EqualString(prefs->newsServerName, gPrefs.newsServerName, false, true)) {
  2256.             NoteMessageNumber(kStrMustRestart);
  2257.         }
  2258.         if (prefs->useInternetConfig != gPrefs.useInternetConfig) {
  2259.             NoteMessageNumber(kStrMustRestartIC);
  2260.         }
  2261.         reauthenticate = strcmp(prefs->authUsername, gPrefs.authUsername) != 0 ||
  2262.             strcmp(prefs->authPassword, gPrefs.authPassword) != 0 ||
  2263.             prefs->authAtStartup && !gPrefs.authAtStartup;
  2264.         MyDisposeHandle(gPrefs.savedMsgDefaultFolderAlias);
  2265.         MyDisposeHandle(gPrefs.savedArtDefaultFolderAlias);
  2266.         MyDisposeHandle(gPrefs.savedBinDefaultFolderAlias);
  2267.         MyDisposeHandle(gPrefs.savedUGLDefaultFolderAlias);
  2268.         MyDisposeHandle(gPrefs.urlHelpers);
  2269.         gPrefs = *prefs;
  2270.         MyICWriteSharedPrefs(kICAllSharedPrefs);
  2271.         ResetNewsServerOptions();
  2272.         AdjustExtractBinariesCommand();
  2273.     } else {
  2274.         MyDisposeHandle(prefs->savedMsgDefaultFolderAlias);
  2275.         MyDisposeHandle(prefs->savedArtDefaultFolderAlias);
  2276.         MyDisposeHandle(prefs->savedBinDefaultFolderAlias);
  2277.         MyDisposeHandle(prefs->savedUGLDefaultFolderAlias);
  2278.         MyDisposeHandle(prefs->urlHelpers);
  2279.     }
  2280.     MyDisposePtr(prefs);
  2281.     prefs = nil;
  2282.     gPrefs.prefsLoc = newLocn;
  2283.     if (reauthenticate && gStartupOK) {
  2284.         err = ReAuthenticate();
  2285.         if (err != noErr) goto exit;
  2286.         if (gPrefs.authPrivateGroups) {
  2287.             err = DoRebuildFullGroupList();
  2288.             if (err != noErr) goto exit;
  2289.         }
  2290.     }
  2291.     SetPort(port);
  2292.     return noErr;
  2293.     
  2294. exit:
  2295.  
  2296.     DisposeArrowPair(gArrowPair);
  2297.     if (dlg != nil) DoClose(dlg);
  2298.     if (prefs != nil) {
  2299.         MyDisposeHandle(prefs->savedMsgDefaultFolderAlias);
  2300.         MyDisposeHandle(prefs->savedArtDefaultFolderAlias);
  2301.         MyDisposeHandle(prefs->savedBinDefaultFolderAlias);
  2302.         MyDisposeHandle(prefs->savedUGLDefaultFolderAlias);
  2303.         MyDisposeHandle(prefs->urlHelpers);
  2304.         MyDisposePtr(prefs);
  2305.     }
  2306.     SetPort(port);
  2307.     return err;
  2308. }
  2309.  
  2310.  
  2311.  
  2312. /*----------------------------------------------------------------------------
  2313.     prefsdlog_InitUPP
  2314.     
  2315.     Initialize UPPs.
  2316. ----------------------------------------------------------------------------*/
  2317.  
  2318. void prefsdlog_InitUPP (void)
  2319. {
  2320.     gInvisibleFilesFilterUPP = NewFileFilterYDProc(InvisibleFilesFilter);
  2321.     gDrawFontSampleUPP = NewUserItemProc(DrawFontSample);
  2322.     gDlgArrowsItemUPP = NewUserItemProc(DrawArrows);
  2323.     gDrawURLListUPP = NewUserItemProc(DrawURLList);
  2324. }